OSDN Git Service

Update docs.
[joypy/Thun.git] / docs / 2._Library_Examples.md
1
2 # Examples (and some documentation) for the Words in the Library
3
4
5 ```python
6 from notebook_preamble import J, V
7 ```
8
9 # Stack Chatter
10 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.)
11
12 ### `clear`
13
14
15 ```python
16 J('1 2 3 clear')
17 ```
18
19     
20
21
22 ### `dup` `dupd`
23
24
25 ```python
26 J('1 2 3 dup')
27 ```
28
29     1 2 3 3
30
31
32
33 ```python
34 J('1 2 3 dupd')
35 ```
36
37     1 2 2 3
38
39
40 ### `enstacken` `disenstacken` `stack` `unstack`
41 (I may have these paired up wrong.  I.e. `disenstacken` should be `unstack` and vice versa.)
42
43
44 ```python
45 J('1 2 3 enstacken') # Replace the stack with a quote of itself.
46 ```
47
48     [3 2 1]
49
50
51
52 ```python
53 J('4 5 6 [3 2 1] disenstacken')  # Unpack a list onto the stack.
54 ```
55
56     4 5 6 3 2 1
57
58
59
60 ```python
61 J('1 2 3 stack')  # Get the stack on the stack.
62 ```
63
64     1 2 3 [3 2 1]
65
66
67
68 ```python
69 J('1 2 3 [4 5 6] unstack')  # Replace the stack with the list on top.
70                             # The items appear reversed but they are not,
71                             # 4 is on the top of both the list and the stack.
72 ```
73
74     6 5 4
75
76
77 ### `pop` `popd` `popop`
78
79
80 ```python
81 J('1 2 3 pop')
82 ```
83
84     1 2
85
86
87
88 ```python
89 J('1 2 3 popd')
90 ```
91
92     1 3
93
94
95
96 ```python
97 J('1 2 3 popop')
98 ```
99
100     1
101
102
103 ### `roll<` `rolldown` `roll>` `rollup`
104 The "down" and "up" refer to the movement of two of the top three items (displacing the third.)
105
106
107 ```python
108 J('1 2 3 roll<')
109 ```
110
111     2 3 1
112
113
114
115 ```python
116 J('1 2 3 roll>')
117 ```
118
119     3 1 2
120
121
122 ### `swap`
123
124
125 ```python
126 J('1 2 3 swap')
127 ```
128
129     1 3 2
130
131
132 ### `tuck` `over`
133
134
135 ```python
136 J('1 2 3 tuck')
137 ```
138
139     1 3 2 3
140
141
142
143 ```python
144 J('1 2 3 over')
145 ```
146
147     1 2 3 2
148
149
150 ### `unit` `quoted` `unquoted`
151
152
153 ```python
154 J('1 2 3 unit')
155 ```
156
157     1 2 [3]
158
159
160
161 ```python
162 J('1 2 3 quoted')
163 ```
164
165     1 [2] 3
166
167
168
169 ```python
170 J('1 [2] 3 unquoted')
171 ```
172
173     1 2 3
174
175
176
177 ```python
178 V('1 [dup] 3 unquoted')  # Unquoting evaluates.  Be aware.
179 ```
180
181                   . 1 [dup] 3 unquoted
182                 1 . [dup] 3 unquoted
183           1 [dup] . 3 unquoted
184         1 [dup] 3 . unquoted
185         1 [dup] 3 . [i] dip
186     1 [dup] 3 [i] . dip
187           1 [dup] . i 3
188                 1 . dup 3
189               1 1 . 3
190             1 1 3 . 
191
192
193 # List words
194
195 ### `concat` `swoncat` `shunt`
196
197
198 ```python
199 J('[1 2 3] [4 5 6] concat')
200 ```
201
202     [1 2 3 4 5 6]
203
204
205
206 ```python
207 J('[1 2 3] [4 5 6] swoncat')
208 ```
209
210     [4 5 6 1 2 3]
211
212
213
214 ```python
215 J('[1 2 3] [4 5 6] shunt')
216 ```
217
218     [6 5 4 1 2 3]
219
220
221 ### `cons` `swons` `uncons`
222
223
224 ```python
225 J('1 [2 3] cons')
226 ```
227
228     [1 2 3]
229
230
231
232 ```python
233 J('[2 3] 1 swons')
234 ```
235
236     [1 2 3]
237
238
239
240 ```python
241 J('[1 2 3] uncons')
242 ```
243
244     1 [2 3]
245
246
247 ### `first` `second` `third` `rest`
248
249
250 ```python
251 J('[1 2 3 4] first')
252 ```
253
254     1
255
256
257
258 ```python
259 J('[1 2 3 4] second')
260 ```
261
262     2
263
264
265
266 ```python
267 J('[1 2 3 4] third')
268 ```
269
270     3
271
272
273
274 ```python
275 J('[1 2 3 4] rest')
276 ```
277
278     [2 3 4]
279
280
281 ### `flatten`
282
283
284 ```python
285 J('[[1] [2 [3] 4] [5 6]] flatten')
286 ```
287
288     [1 2 [3] 4 5 6]
289
290
291 ### `getitem` `at` `of` `drop` `take`
292
293 `at` and `getitem` are the same function. `of == swap at`
294
295
296 ```python
297 J('[10 11 12 13 14] 2 getitem')
298 ```
299
300     12
301
302
303
304 ```python
305 J('[1 2 3 4] 0 at')
306 ```
307
308     1
309
310
311
312 ```python
313 J('2 [1 2 3 4] of')
314 ```
315
316     3
317
318
319
320 ```python
321 J('[1 2 3 4] 2 drop')
322 ```
323
324     [3 4]
325
326
327
328 ```python
329 J('[1 2 3 4] 2 take')  # reverses the order
330 ```
331
332     [2 1]
333
334
335 `reverse` could be defines as `reverse == dup size take`
336
337 ### `remove`
338
339
340 ```python
341 J('[1 2 3 1 4] 1 remove')
342 ```
343
344     [2 3 1 4]
345
346
347 ### `reverse`
348
349
350 ```python
351 J('[1 2 3 4] reverse')
352 ```
353
354     [4 3 2 1]
355
356
357 ### `size`
358
359
360 ```python
361 J('[1 1 1 1] size')
362 ```
363
364     4
365
366
367 ### `swaack`
368 "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.
369
370
371 ```python
372 J('1 2 3 [4 5 6] swaack')
373 ```
374
375     6 5 4 [3 2 1]
376
377
378 ### `choice` `select`
379
380
381 ```python
382 J('23 9 1 choice')
383 ```
384
385     9
386
387
388
389 ```python
390 J('23 9 0 choice')
391 ```
392
393     23
394
395
396
397 ```python
398 J('[23 9 7] 1 select')  # select is basically getitem, should retire it?
399 ```
400
401     9
402
403
404
405 ```python
406 J('[23 9 7] 0 select')
407 ```
408
409     23
410
411
412 ### `zip`
413
414
415 ```python
416 J('[1 2 3] [6 5 4] zip')
417 ```
418
419     [[6 1] [5 2] [4 3]]
420
421
422
423 ```python
424 J('[1 2 3] [6 5 4] zip [sum] map')
425 ```
426
427     [7 7 7]
428
429
430 # Math words
431
432 ### `+` `add`
433
434
435 ```python
436 J('23 9 +')
437 ```
438
439     32
440
441
442 ### `-` `sub`
443
444
445 ```python
446 J('23 9 -')
447 ```
448
449     14
450
451
452 ### `*` `mul`
453
454
455 ```python
456 J('23 9 *')
457 ```
458
459     207
460
461
462 ### `/` `div` `floordiv` `truediv`
463
464
465 ```python
466 J('23 9 /')
467 ```
468
469     2.5555555555555554
470
471
472
473 ```python
474 J('23 -9 truediv')
475 ```
476
477     -2.5555555555555554
478
479
480
481 ```python
482 J('23 9 div')
483 ```
484
485     2
486
487
488
489 ```python
490 J('23 9 floordiv')
491 ```
492
493     2
494
495
496
497 ```python
498 J('23 -9 div')
499 ```
500
501     -3
502
503
504
505 ```python
506 J('23 -9 floordiv')
507 ```
508
509     -3
510
511
512 ### `%` `mod` `modulus` `rem` `remainder`
513
514
515 ```python
516 J('23 9 %')
517 ```
518
519     5
520
521
522 ### `neg`
523
524
525 ```python
526 J('23 neg -5 neg')
527 ```
528
529     -23 5
530
531
532 ### pow
533
534
535 ```python
536 J('2 10 pow')
537 ```
538
539     1024
540
541
542 ### `sqr` `sqrt`
543
544
545 ```python
546 J('23 sqr')
547 ```
548
549     529
550
551
552
553 ```python
554 J('23 sqrt')
555 ```
556
557     4.795831523312719
558
559
560 ### `++` `succ` `--` `pred`
561
562
563 ```python
564 J('1 ++')
565 ```
566
567     2
568
569
570
571 ```python
572 J('1 --')
573 ```
574
575     0
576
577
578 ### `<<` `lshift` `>>` `rshift`
579
580
581 ```python
582 J('8 1 <<')
583 ```
584
585     16
586
587
588
589 ```python
590 J('8 1 >>')
591 ```
592
593     4
594
595
596 ### `average`
597
598
599 ```python
600 J('[1 2 3 5] average')
601 ```
602
603     2.75
604
605
606 ### `range` `range_to_zero` `down_to_zero`
607
608
609 ```python
610 J('5 range')
611 ```
612
613     [4 3 2 1 0]
614
615
616
617 ```python
618 J('5 range_to_zero')
619 ```
620
621     [0 1 2 3 4 5]
622
623
624
625 ```python
626 J('5 down_to_zero')
627 ```
628
629     5 4 3 2 1 0
630
631
632 ### `product`
633
634
635 ```python
636 J('[1 2 3 5] product')
637 ```
638
639     30
640
641
642 ### `sum`
643
644
645 ```python
646 J('[1 2 3 5] sum')
647 ```
648
649     11
650
651
652 ### `min`
653
654
655 ```python
656 J('[1 2 3 5] min')
657 ```
658
659     1
660
661
662 ### `gcd`
663
664
665 ```python
666 J('45 30 gcd')
667 ```
668
669     15
670
671
672 ### `least_fraction`
673 If we represent fractions as a quoted pair of integers [q d] this word reduces them to their ... least common factors or whatever.
674
675
676 ```python
677 J('[45 30] least_fraction')
678 ```
679
680     [3 2]
681
682
683
684 ```python
685 J('[23 12] least_fraction')
686 ```
687
688     [23 12]
689
690
691 # Logic and Comparison
692
693 ### `?` `truthy`
694 Get the Boolean value of the item on the top of the stack.
695
696
697 ```python
698 J('23 truthy')
699 ```
700
701     True
702
703
704
705 ```python
706 J('[] truthy')  # Python semantics.
707 ```
708
709     False
710
711
712
713 ```python
714 J('0 truthy')
715 ```
716
717     False
718
719
720     ? == dup truthy
721
722
723 ```python
724 V('23 ?')
725 ```
726
727             . 23 ?
728          23 . ?
729          23 . dup truthy
730       23 23 . truthy
731     23 True . 
732
733
734
735 ```python
736 J('[] ?')
737 ```
738
739     [] False
740
741
742
743 ```python
744 J('0 ?')
745 ```
746
747     0 False
748
749
750 ### `&` `and` 
751
752
753 ```python
754 J('23 9 &')
755 ```
756
757     1
758
759
760 ### `!=` `<>` `ne`
761
762
763 ```python
764 J('23 9 !=')
765 ```
766
767     True
768
769
770 The usual suspects:
771 - `<` `lt`
772 - `<=` `le`  
773 - `=` `eq`
774 - `>` `gt`
775 - `>=` `ge`
776 - `not`
777 - `or`
778
779 ### `^` `xor`
780
781
782 ```python
783 J('1 1 ^')
784 ```
785
786     0
787
788
789
790 ```python
791 J('1 0 ^')
792 ```
793
794     1
795
796
797 # Miscellaneous
798
799 ### `help`
800
801
802 ```python
803 J('[help] help')
804 ```
805
806     Accepts a quoted symbol on the top of the stack and prints its docs.
807     
808
809
810 ### `parse`
811
812
813 ```python
814 J('[parse] help')
815 ```
816
817     Parse the string on the stack to a Joy expression.
818     
819
820
821
822 ```python
823 J('1 "2 [3] dup" parse')
824 ```
825
826     1 [2 [3] dup]
827
828
829 ### `run`
830 Evaluate a quoted Joy sequence.
831
832
833 ```python
834 J('[1 2 dup + +] run')
835 ```
836
837     [5]
838
839
840 # Combinators
841
842 ### `app1` `app2` `app3`
843
844
845 ```python
846 J('[app1] help')
847 ```
848
849     Given a quoted program on TOS and anything as the second stack item run
850     the program and replace the two args with the first result of the
851     program.
852     
853                 ... x [Q] . app1
854        -----------------------------------
855           ... [x ...] [Q] . infra first
856     
857
858
859
860 ```python
861 J('10 4 [sqr *] app1')
862 ```
863
864     10 160
865
866
867
868 ```python
869 J('10 3 4 [sqr *] app2')
870 ```
871
872     10 90 160
873
874
875
876 ```python
877 J('[app2] help')
878 ```
879
880     Like app1 with two items.
881     
882            ... y x [Q] . app2
883     -----------------------------------
884        ... [y ...] [Q] . infra first
885            [x ...] [Q]   infra first
886     
887
888
889
890 ```python
891 J('10 2 3 4 [sqr *] app3')
892 ```
893
894     10 40 90 160
895
896
897 ### `anamorphism`
898 Given an initial value, a predicate function `[P]`, and a generator function `[G]`, the `anamorphism` combinator creates a sequence.
899
900        n [P] [G] anamorphism
901     ---------------------------
902               [...]
903
904 Example, `range`:
905
906     range == [0 <=] [1 - dup] anamorphism
907
908
909 ```python
910 J('3 [0 <=] [1 - dup] anamorphism')
911 ```
912
913     [2 1 0]
914
915
916 ### `branch`
917
918
919 ```python
920 J('3 4 1 [+] [*] branch')
921 ```
922
923     12
924
925
926
927 ```python
928 J('3 4 0 [+] [*] branch')
929 ```
930
931     7
932
933
934 ### `cleave`
935     ... x [P] [Q] cleave
936
937 From the original Joy docs: "The cleave combinator expects two quotations, and below that an item `x`
938 It first executes `[P]`, with `x` on top, and saves the top result element.
939 Then it executes `[Q]`, again with `x`, and saves the top result.
940 Finally it restores the stack to what it was below `x` and pushes the two
941 results P(X) and Q(X)."
942
943 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`:
944
945     cleave == [i] app2 [popd] dip
946
947
948 ```python
949 J('10 2 [+] [-] cleave')
950 ```
951
952     10 12 8
953
954
955 ### `dip` `dipd` `dipdd`
956
957
958 ```python
959 J('1 2 3 4 5 [+] dip')
960 ```
961
962     1 2 7 5
963
964
965
966 ```python
967 J('1 2 3 4 5 [+] dipd')
968 ```
969
970     1 5 4 5
971
972
973
974 ```python
975 J('1 2 3 4 5 [+] dipdd')
976 ```
977
978     3 3 4 5
979
980
981 ### `dupdip`
982 Expects a quoted program `[Q]` on the stack and some item under it, `dup` the item and `dip` the quoted program under it.
983
984     n [Q] dupdip == n Q n
985
986
987 ```python
988 V('23 [++] dupdip *')  # N(N + 1)
989 ```
990
991             . 23 [++] dupdip *
992          23 . [++] dupdip *
993     23 [++] . dupdip *
994          23 . ++ 23 *
995          24 . 23 *
996       24 23 . *
997         552 . 
998
999
1000 ### `genrec` `primrec`
1001
1002
1003 ```python
1004 J('[genrec] help')
1005 ```
1006
1007     General Recursion Combinator.
1008     
1009                             [if] [then] [rec1] [rec2] genrec
1010       ---------------------------------------------------------------------
1011          [if] [then] [rec1 [[if] [then] [rec1] [rec2] genrec] rec2] ifte
1012     
1013     From "Recursion Theory and Joy" (j05cmp.html) by Manfred von Thun:
1014     "The genrec combinator takes four program parameters in addition to
1015     whatever data parameters it needs. Fourth from the top is an if-part,
1016     followed by a then-part. If the if-part yields true, then the then-part
1017     is executed and the combinator terminates. The other two parameters are
1018     the rec1-part and the rec2-part. If the if-part yields false, the
1019     rec1-part is executed. Following that the four program parameters and
1020     the combinator are again pushed onto the stack bundled up in a quoted
1021     form. Then the rec2-part is executed, where it will find the bundled
1022     form. Typically it will then execute the bundled form, either with i or
1023     with app2, or some other combinator."
1024     
1025     The way to design one of these is to fix your base case [then] and the
1026     test [if], and then treat rec1 and rec2 as an else-part "sandwiching"
1027     a quotation of the whole function.
1028     
1029     For example, given a (general recursive) function 'F':
1030     
1031         F == [I] [T] [R1] [R2] genrec
1032     
1033     If the [I] if-part fails you must derive R1 and R2 from:
1034     
1035         ... R1 [F] R2
1036     
1037     Just set the stack arguments in front, and figure out what R1 and R2
1038     have to do to apply the quoted [F] in the proper way.  In effect, the
1039     genrec combinator turns into an ifte combinator with a quoted copy of
1040     the original definition in the else-part:
1041     
1042         F == [I] [T] [R1]   [R2] genrec
1043           == [I] [T] [R1 [F] R2] ifte
1044     
1045     (Primitive recursive functions are those where R2 == i.
1046     
1047         P == [I] [T] [R] primrec
1048           == [I] [T] [R [P] i] ifte
1049           == [I] [T] [R P] ifte
1050     )
1051     
1052
1053
1054
1055 ```python
1056 J('3 [1 <=] [] [dup --] [i *] genrec')
1057 ```
1058
1059     6
1060
1061
1062 ### `i`
1063
1064
1065 ```python
1066 V('1 2 3 [+ +] i')
1067 ```
1068
1069                 . 1 2 3 [+ +] i
1070               1 . 2 3 [+ +] i
1071             1 2 . 3 [+ +] i
1072           1 2 3 . [+ +] i
1073     1 2 3 [+ +] . i
1074           1 2 3 . + +
1075             1 5 . +
1076               6 . 
1077
1078
1079 ### `ifte`
1080     [predicate] [then] [else] ifte
1081
1082
1083 ```python
1084 J('1 2 [1] [+] [*] ifte')
1085 ```
1086
1087     3
1088
1089
1090
1091 ```python
1092 J('1 2 [0] [+] [*] ifte')
1093 ```
1094
1095     2
1096
1097
1098 ### `infra`
1099
1100
1101 ```python
1102 V('1 2 3 [4 5 6] [* +] infra')
1103 ```
1104
1105                         . 1 2 3 [4 5 6] [* +] infra
1106                       1 . 2 3 [4 5 6] [* +] infra
1107                     1 2 . 3 [4 5 6] [* +] infra
1108                   1 2 3 . [4 5 6] [* +] infra
1109           1 2 3 [4 5 6] . [* +] infra
1110     1 2 3 [4 5 6] [* +] . infra
1111                   6 5 4 . * + [3 2 1] swaack
1112                    6 20 . + [3 2 1] swaack
1113                      26 . [3 2 1] swaack
1114              26 [3 2 1] . swaack
1115              1 2 3 [26] . 
1116
1117
1118 ### `loop`
1119
1120
1121 ```python
1122 J('[loop] help')
1123 ```
1124
1125     Basic loop combinator.
1126     
1127        ... True [Q] loop
1128     -----------------------
1129          ... Q [Q] loop
1130     
1131        ... False [Q] loop
1132     ------------------------
1133               ...
1134     
1135
1136
1137
1138 ```python
1139 V('3 dup [1 - dup] loop')
1140 ```
1141
1142                   . 3 dup [1 - dup] loop
1143                 3 . dup [1 - dup] loop
1144               3 3 . [1 - dup] loop
1145     3 3 [1 - dup] . loop
1146                 3 . 1 - dup [1 - dup] loop
1147               3 1 . - dup [1 - dup] loop
1148                 2 . dup [1 - dup] loop
1149               2 2 . [1 - dup] loop
1150     2 2 [1 - dup] . loop
1151                 2 . 1 - dup [1 - dup] loop
1152               2 1 . - dup [1 - dup] loop
1153                 1 . dup [1 - dup] loop
1154               1 1 . [1 - dup] loop
1155     1 1 [1 - dup] . loop
1156                 1 . 1 - dup [1 - dup] loop
1157               1 1 . - dup [1 - dup] loop
1158                 0 . dup [1 - dup] loop
1159               0 0 . [1 - dup] loop
1160     0 0 [1 - dup] . loop
1161                 0 . 
1162
1163
1164 ### `map` `pam`
1165
1166
1167 ```python
1168 J('10 [1 2 3] [*] map')
1169 ```
1170
1171     10 [10 20 30]
1172
1173
1174
1175 ```python
1176 J('10 5 [[*][/][+][-]] pam')
1177 ```
1178
1179     10 5 [50 2.0 15 5]
1180
1181
1182 ### `nullary` `unary` `binary` `ternary`
1183 Run a quoted program enforcing [arity](https://en.wikipedia.org/wiki/Arity).
1184
1185
1186 ```python
1187 J('1 2 3 4 5 [+] nullary')
1188 ```
1189
1190     1 2 3 4 5 9
1191
1192
1193
1194 ```python
1195 J('1 2 3 4 5 [+] unary')
1196 ```
1197
1198     1 2 3 4 9
1199
1200
1201
1202 ```python
1203 J('1 2 3 4 5 [+] binary')  # + has arity 2 so this is technically pointless...
1204 ```
1205
1206     1 2 3 9
1207
1208
1209
1210 ```python
1211 J('1 2 3 4 5 [+] ternary')
1212 ```
1213
1214     1 2 9
1215
1216
1217 ### `step`
1218
1219
1220 ```python
1221 J('[step] help')
1222 ```
1223
1224     Run a quoted program on each item in a sequence.
1225     
1226             ... [] [Q] . step
1227          -----------------------
1228                    ... .
1229     
1230     
1231            ... [a] [Q] . step
1232         ------------------------
1233                  ... a . Q
1234     
1235     
1236        ... [a b c] [Q] . step
1237     ----------------------------------------
1238                  ... a . Q [b c] [Q] step
1239     
1240     The step combinator executes the quotation on each member of the list
1241     on top of the stack.
1242     
1243
1244
1245
1246 ```python
1247 V('0 [1 2 3] [+] step')
1248 ```
1249
1250                   . 0 [1 2 3] [+] step
1251                 0 . [1 2 3] [+] step
1252         0 [1 2 3] . [+] step
1253     0 [1 2 3] [+] . step
1254           0 1 [+] . i [2 3] [+] step
1255               0 1 . + [2 3] [+] step
1256                 1 . [2 3] [+] step
1257           1 [2 3] . [+] step
1258       1 [2 3] [+] . step
1259           1 2 [+] . i [3] [+] step
1260               1 2 . + [3] [+] step
1261                 3 . [3] [+] step
1262             3 [3] . [+] step
1263         3 [3] [+] . step
1264           3 3 [+] . i
1265               3 3 . +
1266                 6 . 
1267
1268
1269 ### `times`
1270
1271
1272 ```python
1273 V('3 2 1 2 [+] times')
1274 ```
1275
1276                 . 3 2 1 2 [+] times
1277               3 . 2 1 2 [+] times
1278             3 2 . 1 2 [+] times
1279           3 2 1 . 2 [+] times
1280         3 2 1 2 . [+] times
1281     3 2 1 2 [+] . times
1282           3 2 1 . + 1 [+] times
1283             3 3 . 1 [+] times
1284           3 3 1 . [+] times
1285       3 3 1 [+] . times
1286             3 3 . +
1287               6 . 
1288
1289
1290 ### `b`
1291
1292
1293 ```python
1294 J('[b] help')
1295 ```
1296
1297     b == [i] dip i
1298     
1299     ... [P] [Q] b == ... [P] i [Q] i
1300     ... [P] [Q] b == ... P Q
1301     
1302
1303
1304
1305 ```python
1306 V('1 2 [3] [4] b')
1307 ```
1308
1309                 . 1 2 [3] [4] b
1310               1 . 2 [3] [4] b
1311             1 2 . [3] [4] b
1312         1 2 [3] . [4] b
1313     1 2 [3] [4] . b
1314             1 2 . 3 4
1315           1 2 3 . 4
1316         1 2 3 4 . 
1317
1318
1319 ### `while`
1320     [predicate] [body] while
1321
1322
1323 ```python
1324 J('3 [0 >] [dup --] while')
1325 ```
1326
1327     3 2 1 0
1328
1329
1330 ### `x`
1331
1332
1333 ```python
1334 J('[x] help')
1335 ```
1336
1337     x == dup i
1338     
1339     ... [Q] x = ... [Q] dup i
1340     ... [Q] x = ... [Q] [Q] i
1341     ... [Q] x = ... [Q]  Q
1342     
1343
1344
1345
1346 ```python
1347 V('1 [2] [i 3] x')  # Kind of a pointless example.
1348 ```
1349
1350                 . 1 [2] [i 3] x
1351               1 . [2] [i 3] x
1352           1 [2] . [i 3] x
1353     1 [2] [i 3] . x
1354     1 [2] [i 3] . i 3
1355           1 [2] . i 3 3
1356               1 . 2 3 3
1357             1 2 . 3 3
1358           1 2 3 . 3
1359         1 2 3 3 . 
1360
1361
1362 # `void`
1363 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.)
1364
1365
1366 ```python
1367 J('[] void')
1368 ```
1369
1370     False
1371
1372
1373
1374 ```python
1375 J('[[]] void')
1376 ```
1377
1378     True
1379
1380
1381
1382 ```python
1383 J('[[][[]]] void')
1384 ```
1385
1386     True
1387
1388
1389
1390 ```python
1391 J('[[[]][[][]]] void')
1392 ```
1393
1394     False
1395