# 2b: list logic Reverse ### `++flop` Produces the list `a` in reverse order. Accepts ------- `a` is a list. Produces -------- A list. Source ------ ++ flop :: reverse ~/ %flop |* a/(list) => .(a (homo a)) ^+ a =+ b=`_a`~ |- ?~ a b $(a t.a, b [i.a b]) Examples -------- > =a (limo [1 2 3 ~]) > (flop a) ~[3 2 1] *** ### `++homo` Homogenize Produces a `++list` whose type is a fork of all the contained types in the list `a`. Used when you want to make all the types of the elements of a list the same. Accepts ------- `a` is a list. Produces -------- a list. Source ------ ++ homo :: homogenize |* a/(list) ^+ =< $ |% +- $ ?:(*? ~ [i=(snag 0 a) t=$]) -- a Examples -------- > lyst [i=1 t=[i=97 t=[i=2 t=[i=98 t=[i=[~ u=10] t=~]]]]] > (homo lyst) ~[1 97 2 98 [~ u=10]] > =a (limo [1 2 3 ~]) > a [i=1 t=[i=2 t=[i=3 t=~]]] > (homo a) ~[1 2 3] *** ### `++lent` List length Produces the length of any `++list` `a` as an atom. Accepts ------- `a` is a list. Produces -------- an atom. Source ------ ++ lent :: length ~/ %lent |= a/(list) ^- @ =+ b=0 |- ?~ a b $(a t.a, b +(b)) Examples -------- > (lent (limo [1 2 3 4 ~])) 4 > (lent (limo [1 'a' 2 'b' (some 10) ~])) 5 *** ### `++levy` Logical "and" on list Computes the Boolean logical "and" on the results of gate `b` applied to each individual element in `++list` `a`. Accepts ------- `a` is a list. `b` is a gate. Produces -------- A boolean. Source ------ ++ levy ~/ %levy :: all of |* {a/(list) b/$-(* ?)} |- ^- ? ?~ a & ?. (b i.a) | $(a t.a) Examples -------- > =a |=(a/@ (lte a 1)) > (levy (limo [0 1 2 1 ~]) a) %.n > =a |=(a/@ (lte a 3)) > (levy (limo [0 1 2 1 ~]) a) %.y *** ### `++lien` Logical "or" on list Computes the Boolean logical "or" on the results of applying [gate]() `b` to every element of [`++list`]() `a`. Accepts ------- `a` is a list. `b` is a gate. Source ------ ++ lien :: some of ~/ %lien |* {a/(list) b/$-(* ?)} |- ^- ? ?~ a | ?: (b i.a) & $(a t.a) Examples -------- > =a |=(a=@ (gte a 1)) > (lien (limo [0 1 2 1 ~]) a) %.y > =a |=(a=@ (gte a 3)) > (lien (limo [0 1 2 1 ~]) a) %.n *** ### `++limo` List Constructor Turns a null-terminated tuple into a [`++list`](). Accepts ------- `a` is a null-terminated tuple. Produces -------- A `++list`. Source ------ ++ limo :: listify |* a=* ^+ =< $ |% +- $ ?~(a ~ ?:(_? i=-.a t=$ $(a +.a))) -- a Examples -------- > (limo [1 2 3 ~]) [i=1 t=[i=2 t=[i=3 t=~]]] *** ### `++murn` Maybe transform Passes each member of `++list` `a` to gate `b`, which must produce a `++unit`. Produces a new list with all the results that do not produce `~`. Accepts ------- `a` is a list. `b` is a gate that produces a unit. Produces -------- A unit. Source ------ ++ murn :: maybe transform ~/ %murn |* {a/(list) b/$-(* (unit))} |- ?~ a ~ =+ c=(b i.a) ?~ c $(a t.a) [i=u.c t=$(a t.a)] Examples -------- > =a |=(a=@ ?.((gte a 2) ~ (some (add a 10)))) > (murn (limo [0 1 2 3 ~]) a) [i=12 t=[i=13 t=~]] *** ### `++reap` Replicate Replicate: produces a `++list` containing `a` copies of `b`. Accepts ------- `b` is a noun. Produces -------- A list. Source ------ ++ reap :: replicate ~/ %reap |* {a/@ b/*} |- ^- (list _b) ?~ a ~ [b $(a (dec a))] Examples -------- > (reap 20 %a) ~[%a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a] > (reap 5 ~s1) ~[~s1 ~s1 ~s1 ~s1 ~s1] > `@dr`(roll (reap 5 ~s1) add) ~s5 *** ### `++reel` Right fold Right fold: moves right to left across a `++list` `a`, recursively slamming a binary gate `b` with an element from `a` and an accumulator, producing the final value of the accumulator. Accepts ------- `b` is a binary gate. Produces -------- The accumulator, which is a noun. Source ------ ++ reel :: right fold ~/ %reel |* {a/(list) b/_|=({* *} +<+)} |- ^+ +<+.b ?~ a +<+.b (b i.a $(a t.a)) Examples -------- > =sum =|([p=@ q=@] |.((add p q))) > (reel (limo [1 2 3 4 5 ~]) sum) 15 > =a =|([p=@ q=@] |.((sub p q))) > (reel (limo [6 3 1 ~]) a) 4 > (reel (limo [3 6 1 ~]) a) ! subtract-underflow ! exit *** ### `++roll` Left fold Left fold: moves left to right across a list `a`, recursively slamming a binary [gate]() `b` with an element from the [`++list`]() and an accumulator, producing the final value of the accumulator. Accepts ------- `b` is a binary [gate](). Produces -------- The accumulator, which is a [noun](). Source ------ ++ roll :: left fold ~/ %roll |* [a=(list) b=_|=([* *] +<+)] |- ^+ +<+.b ?~ a +<+.b $(a t.a, b b(+<+ (b i.a +<+.b))) Examples -------- > =sum =|([p=@ q=@] |.((add p q))) > (roll (limo [1 2 3 4 5 ~]) sum) q=15 > =a =|([p=@ q=@] |.((sub p q))) > (roll (limo [6 3 1 ~]) a) ! subtract-underflow ! exit > (roll (limo [1 3 6 ~]) a) q=4 *** ### `++scag` Prefix Accepts an atom `a` and [list]() `b`, producing the first `a` elements of the front of the list. Accepts ------- `b` is a list. Produces -------- A list of the same type as `b`. Source ------ ++ scag :: prefix ~/ %scag |* [a=@ b=(list)] |- ^+ b ?: |(?=(~ b) =(0 a)) ~ [i.b $(b t.b, a (dec a))] Examples -------- > (scag 2 (limo [0 1 2 3 ~])) [i=0 t=[i=1 t=~]] > (scag 10 (limo [1 2 3 4 ~])) [i=1 t=[i=2 t=[i=3 t=[i=4 t=~]]]] *** ### `++skid` Separate Separates a `++list` `a` into two lists - Those elements of `a` who produce true when slammed to gate `b` and those who produce `%.n`. Accepts ------- `b` is a gate that accepts one argument and produces a loobean. Produces -------- A cell of two lists. Source ------ ++ skid :: separate ~/ %skid |* {a/(list) b/$-(* ?)} |- ^+ [p=a q=a] ?~ a [~ ~] =+ c=$(a t.a) ?:((b i.a) [[i.a p.c] q.c] [p.c [i.a q.c]]) Examples -------- > =a |=(a/@ (gth a 1)) > (skid (limo [0 1 2 3 ~]) a) [p=[i=2 t=[i=3 t=~]] q=[i=0 t=[i=1 t=~]]] *** ### `++skim` Suffix Cycles through the members of a list `a`, passing them to a gate `b` and producing a list of all of the members that produce `%.y`. Inverse of `++skip`. Accepts ------- `b` is a gate that accepts one argument and produces a boolean. Produces -------- A boolean Source ------ ++ skim :: only ~/ %skim |* {a/(list) b/$-(* ?)} |- ^+ a ?~ a ~ ?:((b i.a) [i.a $(a t.a)] $(a t.a)) Examples -------- > =a |=(a/@ (gth a 1)) > (skim (limo [0 1 2 3 ~]) a) [i=2 t=[i=3 t=~]] *** ### `++skip` Except Cycles through the members of `++list` `a`, passing them to a gate `b`. Produces a list of all of the members that produce `%.n`. Inverse of `++skim`. Accepts ------- `b` is a gate that accepts one argument and produces a loobean. Produces -------- A list of the same type as `a`. Source ------ ++ skip :: except ~/ %skip |* {a/(list) b/$-(* ?)} |- ^+ a ?~ a ~ ?:((b i.a) $(a t.a) [i.a $(a t.a)]) Examples -------- > =a |=(a/@ (gth a 1)) > (skip (limo [0 1 2 3 ~]) a) [i=0 t=[i=1 t=~]] *** ### `++slag` Suffix Accepts an atom `a` and list `b`, producing the remaining elements from `b` starting at `a`. Accepts ------- `b` is a list. Produces -------- A list of the same type as `b`. Source ------ ++ slag :: suffix ~/ %slag |* {a/@ b/(list)} |- ^+ b ?: =(0 a) b ?~ b ~ $(b t.b, a (dec a)) Examples -------- > (slag 2 (limo [1 2 3 4 ~])) [i=3 t=[i=4 t=~]] > (slag 1 (limo [1 2 3 4 ~])) [i=2 t=[i=3 t=[i=4 t=~]]] *** ### `++snag` Index Accepts an atom `a` and a `++list` `b`, producing the element at the index of `a`and failing if the list is null. Lists are 0-indexed. Accepts ------- `b` is a list. Produces -------- Produces an element of `b`, or crashes if no element exists at that index. Source ------ ++ snag :: index ~/ %snag |* {a/@ b/(list)} |- ?~ b ~|('snag-fail' !!) ?: =(0 a) i.b $(b t.b, a (dec a)) Examples -------- > (snag 2 "asdf") ~~d > (snag 0 `(list ,@ud)`~[1 2 3 4]) 1 *** ### `++sort` Quicksort Quicksort: accepts a `++list` `a` and a gate `b` which accepts two nouns and produces a loobean. `++sort` then produces a list of the elements of `a`, sorted according to `b`. Accepts ------- `b` is a gate that ccepts two nouns and produces a boolean. Produces -------- A list Source ------ ++ sort !. :: quicksort ~/ %sort |* {a/(list) b/$-([* *] ?)} => .(a ^.(homo a)) |- ^+ a ?~ a ~ %+ weld $(a (skim t.a |=(c/_i.a (b c i.a)))) ^+ t.a [i.a $(a (skim t.a |=(c/_i.a !(b c i.a))))] Examples -------- > =a =|({p=@ q=@} |.((gth p q))) > (sort (limo [0 1 2 3 ~]) a) ~[3 2 1 0] *** ### `++swag` Infix Similar to `substr` in Javascript: extracts a string infix, beginning at inclusive index `a`, producing `b` number of characters. Accepts ------- `c` is a list. Produces -------- A list of the same type as `c`. Source ------ ++ swag :: infix |* {{a/@ b/@} c/(list)} (scag +<-> (slag +<-< c)) Examples -------- > (swag [2 5] "roly poly") "ly po" > (swag [2 2] (limo [1 2 3 4 ~])) [i=3 t=[i=4 t=~]] *** ### `++turn` Gate to list Accepts a `++list` `a` and a gate `b`. Produces a list with the gate applied to each element of the original list. Accepts ------- `b` is a gate. Produces -------- A list. Source ------ ++ turn :: transform ~/ %turn |* {a/(list) b/$-(* *)} |- ?~ a ~ [i=(b i.a) t=$(a t.a)] Examples -------- > (turn (limo [104 111 111 110 ~]) ,@t) <|h o o n|> > =a |=(a/@ (add a 4)) > (turn (limo [1 2 3 4 ~]) a) ~[5 6 7 8] *** ### `++weld` Concatenate Concatenate two `++list`s `a` and `b`. Accepts ------- `a` and `b` are lists. Source ------ ++ weld :: concatenate ~/ %weld |* {a/(list) b/(list)} => .(a ^.(homo a), b ^.(homo b)) |- ^+ b ?~ a b [i.a $(a t.a)] Examples -------- > (weld "urb" "it") ~[~~u ~~r ~~b ~~i ~~t] > (weld (limo [1 2 ~]) (limo [3 4 ~])) ~[1 2 3 4] *** ### `++welp` Perfect weld Concatenate two `++list`s `a` and `b` without losing their type information to homogenization. Accepts ------- `a` is a list. `b` is a list. Produces -------- A list. Source ------ ++ welp :: perfect weld =| {* *} |% +- $ ?~ +<- +<-(. +<+) +<-(+ $(+<- +<->)) -- Examples -------- > (welp "foo" "bar") "foobar" ~zod/arvo=/hoon/hoon> (welp ~[60 61 62] ~[%a %b %c]) [60 61 62 %a %b %c ~] ~zod/arvo=/hoon/hoon>? (welp ~[60 61 62] ~[%a %b %c]) [60 61 62 %a %b %c ~] [@ud @ud @ud %a %b %c %~] ~zod/arvo=/hoon/hoon> (welp [sa+1 so+2 ~] si/3) [[%sa 1] [%so 2] %si 3] *** ### `++zing` Cons Turns a `++list` of lists into a single list by promoting the elements of each sublist into the higher. Accepts ------- A list of lists. Produces -------- A list. Source ------ ++ zing :: promote =| * |% +- $ ?~ +< +< (welp +<- $(+< +<+)) -- Examples -------- > (zing (limo [(limo ['a' 'b' 'c' ~]) (limo ['e' 'f' 'g' ~]) (limo ['h' 'i' 'j' ~]) ~])) ~['a' 'b' 'c' 'e' 'f' 'g' 'h' 'i' 'j'] > (zing (limo [(limo [1 'a' 2 'b' ~]) (limo [3 'c' 4 'd' ~]) ~])) ~[1 97 2 98 3 99 4 100] ***