on c19bc7a help sign in
1212 lines 18 kB history raw
1:- :~ navhome/'/docs/'
2 sort/'5'
3 title/'2b: List Logic'
4 ==
6;>
8# 2b: list logic
10### `++fand`
12All indices in `list`
14Produces the indices of all occurrences of `nedl` in `hstk` as a `list` of
15atoms.
17#### Accepts
19`nedl` is a list.
21`hstk` is a list.
23#### Produces
25A `list`.
27#### Source
29```
30 ++ fand
31 ~/ %fand
32 |= [nedl=(list) hstk=(list)]
33 =| i=@ud
34 =| fnd=(list @ud)
35 |- ^+ fnd
36 =+ [n=nedl h=hstk]
37 |-
38 ?: |(?=($~ n) ?=($~ h))
39 (flop fnd)
40 ?: =(i.n i.h)
41 ?~ t.n
42 ^$(i +(i), hstk +.hstk, fnd [i fnd])
43 $(n t.n, h t.h)
44 ^$(i +(i), hstk +.hstk)
45```
47#### Examples
49```
50 > (fand ~[3] ~[1 2 3])
51 ~[2]
53 > (fand ~[4] ~[1 2 3])
54 ~
56 > (fand ~['a'] "cbabab")
57 ~[2 4]
59 > (fand "ba" "cbabab")
60 ~[1 3]
61```
64---
65### `++find`
67First index in `list`
69Produces the index of the first occurrence of `nedl` in `hstk` as the `unit`
70of an atom.
72#### Accepts
74`nedl` is a list.
76`hstk` is a list.
78#### Produces
80The `unit` of an atom.
82#### Source
84```
85 ++ find
86 ~/ %find
87 |= [nedl=(list) hstk=(list)]
88 =| i=@ud
89 |- ^- (unit @ud)
90 =+ [n=nedl h=hstk]
91 |-
92 ?: |(?=($~ n) ?=($~ h))
93 ~
94 ?: =(i.n i.h)
95 ?~ t.n
96 `i
97 $(n t.n, h t.h)
98 ^$(i +(i), hstk +.hstk)
99```
101#### Examples
103```
104 > (find [3]~ ~[1 2 3])
105 [~ u=2]
107 > (find [4]~ ~[1 2 3])
108 ~
110 > (find ['c']~ "cbabab")
111 [~ u=0]
113 > (find "ab" "cbabab")
114 [~ u=1]
116 > (find "bab" "cbabab")
117 [~ u=2]
118```
120---
121### `++flop`
123Reverse
125Produces the `list` `a` in reverse order.
127#### Accepts
129`a` is a `list`.
131#### Produces
133A `list`.
135#### Source
137```
138 ++ flop
139 ~/ %flop
140 |* a=(list)
141 => .(a (homo a))
142 ^+ a
143 =+ b=`_a`~
144 |-
145 ?~ a b
146 $(a t.a, b [i.a b])
147```
150#### Examples
152```
153 > =a [1 2 3 ~]
154 > (flop a)
155 ~[3 2 1]
157 > (flop (flop a))
158 ~[1 2 3]
159```
161---
162### `++gulf`
164List from range
166Produces a `list` composed of each consecutive integer starting from `a` and
167ending with `b`. `a` and `b` are themselves included.
169#### Accepts
171`a` is an atom.
173`b` is an atom.
175#### Produces
177a `list`.
179#### Source
181```
182 ++ gulf
183 |= [a=@ b=@]
184 ^- (list @)
185 ?:(=(a +(b)) ~ [a $(a +(a))])
186```
188#### Examples
190```
191 > (gulf 1 6)
192 ~[1 2 3 4 5 6]
194 > `(list @t)`(gulf 99 106)
195 <|c d e f g h i j|>
196```
198---
199### `++homo`
201Homogenize
203Produces a `list` whose type is a fork of all the contained types in the
204list `a`. Used when you want to make all the types of the elements of a list the
205same.
207#### Accepts
209`a` is a `list`.
211#### Produces
213a `list`.
215#### Source
217```
218 ++ homo
219 |* a=(list)
220 ^+ =< $
221 |% +- $ ?:(*? ~ [i=(snag 0 a) t=$])
222 --
223 a
224```
226#### Examples
228```
229 > lyst
230 [i=1 t=[i=97 t=[i=2 t=[i=98 t=[i=[~ u=10] t=~]]]]]
232 > (homo lyst)
233 ~[1 97 2 98 [~ u=10]]
235 > =a (limo [1 2 3 ~])
236 > a
237 [i=1 t=[i=2 t=[i=3 t=~]]]
239 > (homo a)
240 ~[1 2 3]
241```
244---
245### `++lent`
247List length
249Produces the length of any `list` `a` as an atom.
251#### Accepts
253`a` is a `list`.
255#### Produces
257an atom.
259#### Source
261```
262 ++ lent
263 ~/ %lent
264 |= a=(list)
265 ^- @
266 =+ b=0
267 |-
268 ?~ a b
269 $(a t.a, b +(b))
270```
272#### Examples
274```
275 > (lent [1 2 3 4 ~]))
276 4
278 > (lent [1 'a' 2 'b' (some 10) ~])
279 5
280```
283---
284### `++levy`
286Logical "and" on list
288Computes the Boolean logical "and" on the results of gate `b` applied to each individual element in `list` `a`.
290#### Accepts
292`a` is a list.
294`b` is a gate.
296#### Produces
298A boolean.
300#### Source
302```
303 ++ levy
304 ~/ %levy :: all of
305 |* [a=(list) b=$-(* ?)]
306 |- ^- ?
307 ?~ a &
308 ?. (b i.a) |
309 $(a t.a)
310```
312#### Examples
314```
315 > =a |=(a=@ (lte a 1))
316 > (levy `(list @)`[0 1 2 1 ~] a)
317 %.n
319 > =a |=(a=@ (lte a 3))
320 > (levy `(list @)`[0 1 2 1 ~] a)
321 %.y
322```
325---
327### `++lien`
329Logical "or" on list
331Computes the Boolean logical "or" on the results of applying `gate` `b` to
332every element of `++list` `a`.
334#### Accepts
336`a` is a list.
338`b` is a gate.
340#### Source
342```
343 ++ lien
344 ~/ %lien
345 |* [a=(list) b=$-(* ?)]
346 |- ^- ?
347 ?~ a |
348 ?: (b i.a) &
349 $(a t.a)
350```
352#### Examples
354```
355 > =a |=(a=@ (gte a 1))
356 > (lien `(list @)`[0 1 2 1 ~] a)
357 %.y
359 > =a |=(a=@ (gte a 3))
360 > (lien `(list @)`[0 1 2 1 ~]) a)
361 %.n
362```
365---
366### `++limo`
368List Constructor
370Turns a null-terminated tuple into a `list`.
372#### Accepts
374`a` is a null-terminated tuple.
376#### Produces
378A `++list`.
380#### Source
382```
383 ++ limo :: listify
384 |* a=*
385 ^+ =< $
386 |% +- $ ?~(a ~ ?:(_? i=-.a t=$ $(a +.a)))
387 --
388 a
389```
391#### Examples
393```
394 > (limo [1 2 3 ~])
395 [i=1 t=[i=2 t=[i=3 t=~]]]
396```
399---
400### `++murn`
402Maybe transform
404Passes each member of `list` `a` to gate `b`, which must produce a
405`unit`. Produces a new list with all the results that do not produce
406`~`.
408#### Accepts
410`a` is a list.
412`b` is a gate that produces a unit.
414#### Produces
416A unit.
418#### Source
420```
421 ++ murn :: maybe transform
422 ~/ %murn
423 |* [a=(list) b=$-(* (unit))]
424 |-
425 ?~ a ~
426 =+ c=(b i.a)
427 ?~ c
428 $(a t.a)
429 [i=u.c t=$(a t.a)]
430```
432#### Examples
434```
435 > =a |=(a=@ ?.((gte a 2) ~ (some (add a 10))))
436 > (murn `(list @)`[0 1 2 3 ~] a)
437 [i=12 t=[i=13 t=~]]
438```
441---
442### `++oust`
444Remove
446Removes elements from list `c` beginning at inclusive index `a`, removing `b`
447number of elements.
449#### Accepts
451`c` is a list.
453#### Produces
455A `++list`.
457#### Source
459```
460 ++ oust :: remove
461 ~/ %oust
462 |* [[a=@ b=@] c=(list)]
463 (weld (scag a c) (slag (add a b) c))
464```
466#### Examples
468```
469 > (oust [4 5] "good day, urbit!")
470 "good urbit!"
472 > (oust [2 2] `(list @)`[1 2 3 4 ~])
473 ~[1 2]
474```
477---
478### `++reap`
480Replicate
482Replicate: produces a `list` containing `a` copies of `b`.
484#### Accepts
486`a` is an atom.
488`b` is a noun.
490#### Produces
492A list.
494#### Source
496```
497 ++ reap :: replicate
498 ~/ %reap
499 |* [a=@ b=*]
500 |- ^- (list _b)
501 ?~ a ~
502 [b $(a (dec a))]
503```
505#### Examples
507```
508 > (reap 20 %a)
509 ~[%a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a]
511 > (reap 5 ~s1)
512 ~[~s1 ~s1 ~s1 ~s1 ~s1]
514 > `@dr`(roll (reap 5 ~s1) add)
515 ~s5
516```
519---
520### `++reel`
522Right fold
524Right fold: moves right to left across a `list` `a`, recursively slamming
525a binary gate `b` with an element from `a` and an accumulator, producing
526the final value of the accumulator.
528(To "slam" means to call a gate and give it a sample/samples. In this instance,
529`a` is the list of samples that are given to the gate b.)
531#### Accepts
533`a` is a list.
535`b` is a binary gate.
537#### Produces
539The accumulator, which is a noun.
541#### Source
543```
544 ++ reel
545 ~/ %reel
546 |* [a=(list) b=_|=([* *] +<+)]
547 |- ^+ +<+.b
548 ?~ a
549 +<+.b
550 (b i.a $(a t.a))
551```
553#### Examples
555```
556 > =sum =|([p=@ q=@] |.((add p q)))
557 > (reel (limo [1 2 3 4 5 ~]) sum)
558 15
560 > =a =|([p=@ q=@] |.((sub p q)))
561 > (reel (limo [6 3 1 ~]) a)
562 4
564 > (reel (limo [3 6 1 ~]) a)
565 ! subtract-underflow
566 ! exit
567```
570---
571### `++roll`
573Left fold
575Left fold: moves left to right across a list `a`, recursively slamming a
576binary gate `b` with an element from the `list` and an accumulator,
577producing the final value of the accumulator.
579(To "slam" means to call a gate and give it a sample/samples. In this instance,
580`a` is the list of samples that are given to the gate b.)
582#### Accepts
584`a` is a list.
586`b` is a binary gate.
588#### Produces
590The accumulator, which is a noun.
592#### Source
594```
595 ++ roll :: left fold
596 ~/ %roll
597 |* [a=(list) b=_|=([* *] +<+)]
598 |- ^+ +<+.b
599 ?~ a
600 +<+.b
601 $(a t.a, b b(+<+ (b i.a +<+.b)))
602```
604#### Examples
606```
607 > =sum =|([p=@ q=@] |.((add p q)))
608 > (roll (limo [1 2 3 4 5 ~]) sum)
609 q=15
611 > =a =|([p=@ q=@] |.((sub p q)))
612 > (roll (limo [6 3 1 ~]) a)
613 ! subtract-underflow
614 ! exit
616 > (roll (limo [1 3 6 ~]) a)
617 q=4
618```
621---
622### `++scag`
624Prefix
626Accepts an atom `a` and `list` `b`, producing the first `a` elements of
627the front of the list.
629#### Accepts
631`a` is an atom.
633`b` is a list.
635#### Produces
637A list of the same type as `b`.
639#### Source
641```
642 ++ scag :: prefix
643 ~/ %scag
644 |* [a=@ b=(list)]
645 |- ^+ b
646 ?: |(?=(~ b) =(0 a)) ~
647 [i.b $(b t.b, a (dec a))]
648```
650#### Examples
652```
653 > (scag 2 `(list @)`[1 2 3 4 ~])
654 [i=0 t=~[1]]
656 > (scag 10 `(list @)`[1 2 3 4 ~])
657 [i=1 t=~[2 3 4]]
658```
661---
662### `++skid`
664Separate
666Separates a `list` `a` into two lists - Those elements of `a` who produce
667true when slammed to gate `b` and those who produce `%.n`.
669(To "slam" means to call a gate and give it a sample/samples. In this instance,
670`a` is the list of samples that are given to the gate `b`.)
672#### Accepts
674`a` is a list.
676`b` is a gate that accepts one argument and produces a flag.
678#### Produces
680A cell of two lists.
682#### Source
684```
685 ++ skid :: separate
686 ~/ %skid
687 |* [a=(list) b=$-(* ?)]
688 |- ^+ [p=a q=a]
689 ?~ a [~ ~]
690 =+ c=$(a t.a)
691 ?:((b i.a) [[i.a p.c] q.c] [p.c [i.a q.c]])
692```
695#### Examples
697```
698 > =a |=(a=@ (gth a 1))
699 > (skid `(list @)`[0 1 2 3 ~]) a)
700 (skid `(list @)`[0 1 2 3 ~]) a)
701```
704---
705### `++skim`
707Suffix
709Cycles through the members of a list `a`, passing them to a gate `b` and
710producing a list of all of the members that produce `%.y`. Inverse of
711`skip`.
713#### Accepts
715`a` is a list.
717`b` is a gate that accepts one argument and produces a boolean.
719#### Produces
721A flag.
723#### Source
725```
726 ++ skim :: only
727 ~/ %skim
728 |* [a=(list) b=$-(* ?)]
729 |-
730 ^+ a
731 ?~ a ~
732 ?:((b i.a) [i.a $(a t.a)] $(a t.a))
733```
735#### Examples
737```
738 > =a |=(a=@ (gth a 1))
739 > (skim `(list @)`[0 1 2 3 ~] a)
740 [i=2 t=~[3]]
741```
743---
744### `++skip`
746Except
748Cycles through the members of `list` `a`, passing them to a gate `b`.
749Produces a list of all of the members that produce `%.n`. Inverse of
750`skim`.
752#### Accepts
754`a` is a list.
756`b` is a gate that accepts one argument and produces a flag.
758#### Produces
760A list of the same type as `a`.
762#### Source
764```
765 ++ skip :: except
766 ~/ %skip
767 |* [a=(list) b=$-(* ?)]
768 |-
769 ^+ a
770 ?~ a ~
771 ?:((b i.a) $(a t.a) [i.a $(a t.a)])
772```
774#### Examples
776```
777 > =a |=(a=@ (gth a 1))
778 > (skip `(l)`[0 1 2 3 ~]) a)
779 [i=0 t=[i=1 t=~]]
780```
783---
784### `++slag`
786Suffix
788Accepts an atom `a` and list `b`, producing the remaining elements from
789`b` starting at `a`.
791#### Accepts
793`b` is a list.
795#### Produces
797A list of the same type as `b`.
799#### Source
801```
802 ++ slag :: suffix
803 ~/ %slag
804 |* [a=@ b=(list)]
805 |- ^+ b
806 ?: =(0 a) b
807 ?~ b ~
808 $(b t.b, a (dec a))
809```
811#### Examples
813```
814 > (slag 2 (limo [1 2 3 4 ~]))
815 [i=3 t=[i=4 t=~]]
816 > (slag 1 (limo [1 2 3 4 ~]))
817 [i=2 t=[i=3 t=[i=4 t=~]]]
818```
821---
822### `++snag`
824Index
826Accepts an atom `a` and a `++list` `b`, producing the element at the index
827of `a`and failing if the list is null. Lists are 0-indexed.
829#### Accepts
831`b` is a list.
833#### Produces
835Produces an element of `b`, or crashes if no element exists at that index.
837#### Source
839```
840 ++ snag :: index
841 ~/ %snag
842 |* [a=@ b=(list)]
843 |-
844 ?~ b
845 ~|('snag-fail' !!)
846 ?: =(0 a) i.b
847 $(b t.b, a (dec a))
848```
850#### Examples
852```
853 > (snag 2 "asdf")
854 ~~d
855 > (snag 0 `(list @ud)`~[1 2 3 4])
856 1
857```
860---
861### `++sort`
863Quicksort
865Quicksort: accepts a `++list` `a` and a gate `b` which accepts two nouns and
866produces a flag. `++sort` then produces a list of the elements of `a`,
867sorted according to `b`.
869#### Accepts
871`b` is a gate that accepts two nouns and produces a boolean.
873#### Produces
875A list
877#### Source
879```
880 ++ sort !. :: quicksort
881 ~/ %sort
882 |* [a=(list) b=$-([* *] ?)]
883 => .(a ^.(homo a))
884 |- ^+ a
885 ?~ a ~
886 %+ weld
887 $(a (skim t.a |=(c/_i.a (b c i.a))))
888 ^+ t.a
889 [i.a $(a (skim t.a |=(c/_i.a !(b c i.a))))]
890```
892#### Examples
894```
895 > =a =|([p/@ q/@] |.((gth p q)))
896 > (sort (limo [0 1 2 3 ~]) a)
897 ~[3 2 1 0]
898```
901---
902### `++spin`
904Gate to list, with state
906Accepts a `++list` `a`, a gate `b`, and some state `c`. Produces a list with
907the gate applied to each element of the original list. `b` is called with
908a tuple -- the head is an element of `a` and the tail is the state `c`, and
909should produce a tuple of the transformed element and the (potentially
910modified) state `c`.
912#### Accepts
914`a` is a `++list`.
916`b` is a gate.
918`c` is a noun.
920#### Produces
922A list.
924#### Source
926```
927 ++ spin
928 ~/ %spin
929 |* [a=(list) b=* c=_|=(^ [** +<+])]
930 => .(c `$-([_?>(?=(^ a) i.a) _b] [_-:(c) _b])`c)
931 =/ acc=(list _-:(c)) ~
932 |- ^- (pair _acc _b)
933 ?~ a
934 [(flop acc) b]
935 =^ res b (c i.a b)
936 $(acc [res acc], a t.a)
937```
939#### Examples
941```
942 > %^ spin (limo ~[4 5 6]) :: trivial example -- does nothing with the state
943 |=([n=@ a=@] [n a])
944 0
945 ~[4 5 6]
947 > %^ spin (limo ~[4 5 6]) :: `p` as the index and `q` as the list element
948 |=([n=@ a=@] [`(pair)`[a n] +(a)])
949 0
950 ~[[p=0 q=4] [p=1 q=5] [p=2 q=6]]
952 > %^ spin (reap 10 0) :: Create 10 random numbers less than `10`
953 |=([n=@ rng=_og] (rads:rng 10))
954 ~(. og eny)
955 ~[5 5 9 4 1 7 9 9 9 6]
956```
958#### Discussion
960`(~(rads og eny) 2)` creates a random number less than `2`, seeding the RNG
961with entropy (`eny`). The head of the product is the random number, the tail
962is the continuation of the RNG.
966---
967### `++spun`
969Gate to list, with state
971Accepts a `list` `a` and a gate `b`. `c` is internal state, initially
972derived by *bunting* the tail of the sample of gate `b`, instead of
973being passed in explicitly as in `++spin`. Produces a list with the
974gate applied to each element of the original list. `b` is called with a tuple --
975the head is an element of `a` and the tail is the state `c`, and should
976produce a tuple of the transformed element and the (potentially modified)
977state `c`.
979#### Accepts
981`a` is a `++list`.
983`b` is a gate.
985#### Produces
987A list.
989#### Source
991```
992 ++ spun
993 ~/ %spun
994 |* [a=(list) b=_|=(^ [** +<+])]
995 p:(spin a +<+.b b)
996```
998#### Examples
1000```
1001 > %+ spun (limo ~[4 5 6]) :: `p` as the index and `q` as the list element
1002 |=([n=@ a=@] [`(pair)`[a n] +(a)])
1003 ~[[p=0 q=4] [p=1 q=5] [p=2 q=6]]
1005 > =l (limo ~[7 8 9])
1006 > %+ spun (limo ~[4 5 6]) :: joins two lists into a list of pairs
1007 |=([n=@ a=@] [`(pair)`[(snag a l) n] +(a)])
1008 ~[[p=7 q=4] [p=8 q=5] [p=9 q=6]]
1009```
1012---
1013### `++swag`
1015Infix
1017Similar to `substr` in Javascript: extracts a string infix, beginning at
1018inclusive index `a`, producing `b` number of characters.
1020#### Accepts
1022`c` is a list.
1024#### Produces
1026A list of the same type as `c`.
1028#### Source
1030```
1031 ++ swag
1032 |* [[a=@ a=@] c=(list)]
1033 (scag +<-> (slag +<-< c))
1034```
1036#### Examples
1038```
1039 > (swag [2 5] "roly poly")
1040 "ly po"
1042 > (swag [2 2] (limo [1 2 3 4 ~]))
1043 [i=3 t=[i=4 t=~]]
1044```
1047---
1048### `++turn`
1050Gate to list
1052Accepts a `++list` `a` and a gate `b`. Produces a list with the gate applied
1053to each element of the original list.
1055#### Accepts
1057`b` is a gate.
1059#### Produces
1061A list.
1063#### Source
1065```
1066 ++ turn
1067 ~/ %turn
1068 |* [a=(list) b=gate]
1069 |-
1070 ?~ a ~
1071 [i=(b i.a) t=$(a t.a)]
1072```
1074#### Examples
1076```
1077 > (turn (limo [104 111 111 110 ~]) @t)
1078 <|h o o n|>
1080 > =a |=(a=@ (add a 4))
1081 > (turn (limo [1 2 3 4 ~]) a)
1082 ~[5 6 7 8]
1083```
1085#### Discussion
1087`turn` is Hoon's version of 'map' in Haskell.
1089---
1090### `++weld`
1092Concatenate
1094Concatenate two `++list`s `a` and `b`.
1096#### Accepts
1098`a` and `b` are lists.
1100#### Source
1102```
1103 ++ weld
1104 ~/ %weld
1105 |* [a=(list) b=(list)]
1106 => .(a ^.(homo a), b ^.(homo b))
1107 |- ^+ b
1108 ?~ a b
1109 [i.a $(a t.a)]
1110```
1112#### Examples
1114```
1115 > (weld "urb" "it")
1116 ~[~~u ~~r ~~b ~~i ~~t]
1118 > (weld (limo [1 2 ~]) (limo [3 4 ~]))
1119 ~[1 2 3 4]
1120```
1123---
1124### `++welp`
1126Perfect weld
1128Concatenate two `++list`s `a` and `b` without losing their type information
1129to homogenization.
1131#### Accepts
1133`a` is a list.
1135`b` is a list.
1137#### Produces
1139A list.
1141#### Source
1143```
1144 ++ welp
1145 =| [* *]
1146 |%
1147 +- $
1148 ?~ +<-
1149 +<-(. +<+)
1150 +<-(+ $(+<- +<->))
1151 --
1152```
1154#### Examples
1156```
1157 > (welp "foo" "bar")
1158 "foobar"
1160 > (welp ~[60 61 62] ~[%a %b %c])
1161 [60 61 62 %a %b %c ~]
1163 > ? (welp ~[60 61 62] ~[%a %b %c])
1164 {@ud @ud @ud $a $b $c $~}
1165 [60 61 62 %a %b %c ~]
1167 > (welp [sa+1 so+2 ~] si=3)
1168 [[%sa 1] [%so 2] si=3]
1169```
1172---
1173### `++zing`
1175Cons
1177Turns a `++list` of lists into a single list by promoting the elements of
1178each sublist into the higher.
1180#### Accepts
1182A list of lists.
1184#### Produces
1186A list.
1188#### Source
1190```
1191 ++ zing
1192 =| *
1193 |%
1194 +- $
1195 ?~ +<
1196 +<
1197 (welp +<- $(+< +<+))
1198 --
1199```
1202#### Examples
1204```
1205 > (zing (limo [(limo ['a' 'b' 'c' ~]) (limo ['e' 'f' 'g' ~]) (limo ['h' 'i' 'j' ~]) ~]))
1206 ~['a' 'b' 'c' 'e' 'f' 'g' 'h' 'i' 'j']
1208 > (zing (limo [(limo [1 'a' 2 'b' ~]) (limo [3 'c' 4 'd' ~]) ~]))
1209 ~[1 97 2 98 3 99 4 100]
1210```
1212---