# 2b: List Logic

### `++fand`

All indices in `list`

Produces the indices of all occurrences of `nedl` in `hstk` as a `list` of atoms.

#### Accepts

`nedl` is a list.

`hstk` is a list.

#### Produces

A `list`.

#### Source

```    ++  fand
~/  %fand
|=  [nedl=(list) hstk=(list)]
=|  i=@ud
=|  fnd=(list @ud)
|-  ^+  fnd
=+  [n=nedl h=hstk]
|-
?:  |(?=(\$~ n) ?=(\$~ h))
(flop fnd)
?:  =(i.n i.h)
?~  t.n
^\$(i +(i), hstk +.hstk, fnd [i fnd])
\$(n t.n, h t.h)
^\$(i +(i), hstk +.hstk)
```

#### Examples

```    > (fand ~[3] ~[1 2 3])
~[2]

> (fand ~[4] ~[1 2 3])
~

> (fand ~['a'] "cbabab")
~[2 4]

> (fand "ba" "cbabab")
~[1 3]
```

### `++find`

First index in `list`

Produces the index of the first occurrence of `nedl` in `hstk` as the `unit` of an atom.

#### Accepts

`nedl` is a list.

`hstk` is a list.

#### Produces

The `unit` of an atom.

#### Source

```    ++  find
~/  %find
|=  [nedl=(list) hstk=(list)]
=|  i=@ud
|-   ^-  (unit @ud)
=+  [n=nedl h=hstk]
|-
?:  |(?=(\$~ n) ?=(\$~ h))
~
?:  =(i.n i.h)
?~  t.n
`i
\$(n t.n, h t.h)
^\$(i +(i), hstk +.hstk)
```

#### Examples

```    > (find [3]~ ~[1 2 3])
[~ u=2]

> (find [4]~ ~[1 2 3])
~

> (find ['c']~ "cbabab")
[~ u=0]

> (find "ab" "cbabab")
[~ u=1]

> (find "bab" "cbabab")
[~ u=2]
```

### `++flop`

Reverse

Produces the `list` `a` in reverse order.

#### Accepts

`a` is a `list`.

#### Produces

A `list`.

#### Source

```    ++  flop
~/  %flop
|*  a=(list)
=>  .(a (homo a))
^+  a
=+  b=`_a`~
|-
?~  a  b
\$(a t.a, b [i.a b])
```

#### Examples

```    > =a [1 2 3 ~]
> (flop a)
~[3 2 1]

> (flop (flop a))
~[1 2 3]
```

### `++gulf`

List from range

Produces a `list` composed of each consecutive integer starting from `a` and ending with `b`. `a` and `b` are themselves included.

#### Accepts

`a` is an atom.

`b` is an atom.

#### Produces

a `list`.

#### Source

```    ++  gulf
|=  [a=@ b=@]
^-  (list @)
?:(=(a +(b)) ~ [a \$(a +(a))])
```

#### Examples

```    > (gulf 1 6)
~[1 2 3 4 5 6]

> `(list @t)`(gulf 99 106)
<|c d e f g h i j|>
```

### `++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
|*  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]
```

### `++join`

Constructs a new `list`, placing `sep` between every element of `lit`.

#### Accepts

`sep` is a `noun`.

`lit` is a `list`.

#### Produces

a `list`.

#### Source

```    ++  join
|*  [sep=* lit=(list)]
=.  sep  `_?>(?=(^ lit) i.lit)`sep
?~  lit  ~
=|  out=(list _?>(?=(^ lit) i.lit))
|-  ^+  out
?~  t.lit
(flop [i.lit out])
\$(out [sep i.lit out], lit t.lit)
```

#### Examples

```    > (join ' ' "hoon")
"h o o n"

> (join 0 `(list @)`~[1 2 3])
~[1 0 2 0 3]
```

### `++lent`

List length

Produces the length of any `list` `a` as an atom.

#### Accepts

`a` is a `list`.

an atom.

#### Source

```    ++  lent
~/  %lent
|=  a=(list)
^-  @
=+  b=0
|-
?~  a  b
\$(a t.a, b +(b))
```

#### Examples

```    > (lent [1 2 3 4 ~]))
4

> (lent [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.

A boolean.

#### Source

```    ++  levy
~/  %levy                                             ::  all of
|*  [a=(list) b=\$-(* ?)]
|-  ^-  ?
?~  a  &
?.  (b i.a)  |
\$(a t.a)
```

#### Examples

```    > =a |=(a=@ (lte a 1))
> (levy `(list @)`[0 1 2 1 ~] a)
%.n

> =a |=(a=@ (lte a 3))
> (levy `(list @)`[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
~/  %lien
|*  [a=(list) b=\$-(* ?)]
|-  ^-  ?
?~  a  |
?:  (b i.a)  &
\$(a t.a)
```

#### Examples

```    > =a |=(a=@ (gte a 1))
> (lien `(list @)`[0 1 2 1 ~] a)
%.y

> =a |=(a=@ (gte a 3))
> (lien `(list @)`[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.

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 `(list @)`[0 1 2 3 ~] a)
[i=12 t=[i=13 t=~]]
```

### `++oust`

Remove

Removes elements from list `c` beginning at inclusive index `a`, removing `b` number of elements.

#### Accepts

`c` is a list.

#### Produces

A `++list`.

#### Source

```    ++  oust                                                ::  remove
~/  %oust
|*  [[a=@ b=@] c=(list)]
(weld (scag a c) (slag (add a b) c))
```

#### Examples

```    > (oust [4 5] "good day, urbit!")
"good urbit!"

> (oust [2 2] `(list @)`[1 2 3 4 ~])
~[1 2]
```

### `++reap`

Replicate

Replicate: produces a `list` containing `a` copies of `b`.

#### Accepts

`a` is an atom.

`b` is a noun.

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.

(To "slam" means to call a gate and give it a sample/samples. In this instance, `a` is the list of samples that are given to the gate b.)

#### Accepts

`a` is a list.

`b` is a binary gate.

#### Produces

The accumulator, which is a noun.

#### Source

```    ++  reel
~/  %reel
|*  [a=(list) b=_|=([* *] +<+)]
|-  ^+  +<+.b
?~  a
+<+.b
(b i.a \$(a t.a))
```

#### Examples

```    > (reel `(list @)`[1 2 3 4 5 ~] add)
15

> (reel `(list @)`[6 3 1 ~] sub)
4

> (reel `(list @)`[3 6 1 ~] sub)
! 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.

(To "slam" means to call a gate and give it a sample/samples. In this instance, `a` is the list of samples that are given to the gate b.)

#### Accepts

`a` is a list.

`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

```    > (roll `(list @)`[1 2 3 4 5 ~] add)
q=15

> (roll `(list @)`[6 3 1 ~] sub)
! subtract-underflow
! exit

> (roll `(list @)`[1 3 6 ~] sub)
q=4
```

### `++scag`

Prefix

Accepts an atom `a` and `list` `b`, producing the first `a` elements of the front of the list.

#### Accepts

`a` is an atom.

`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 `(list @)`[1 2 3 4 ~])
[i=1 t=~[2]]

> (scag 10 `(list @)`[1 2 3 4 ~])
[i=1 t=~[2 3 4]]
```

### `++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`.

(To "slam" means to call a gate and give it a sample/samples. In this instance, `a` is the list of samples that are given to the gate `b`.)

#### Accepts

`a` is a list.

`b` is a gate that accepts one argument and produces a flag.

#### 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 `(list @)`[0 1 2 3 ~] a)
[p=[i=2 t=~[3]] q=[i=0 t=~[1]]]
```

### `++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

`a` is a list.

`b` is a gate that accepts one argument and produces a boolean.

A list.

#### 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 `(list @)`[0 1 2 3 ~] a)
[i=2 t=~[3]]
```

### `++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

`a` is a list.

`b` is a gate that accepts one argument and produces a flag.

#### 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 `(l)`[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

`a` is an atom.

`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

`a` is an atom.

`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
```

### `++snoc`

Append

Accepts a `++list` `a` and a noun `b`, producing the list of `b` appended to `a`.

#### Accepts

`a` is a list.

`b` is a noun.

#### Produces

Produces a list of `b` appended to `a`.

#### Source

```    ++  snoc
|*  [a/(list) b/*]
(weld a ^+(a [b]~))
```

#### Examples

```    > `tape`(zing (snoc `(list tape)`~["a" "bc" "def"] "g"))
"abcdefg"
> (snoc `(list @ud)`~[1 2 3] 4)
~[1 2 3 4]
```

### `++snap`

Replace item at index

Accepts a `list` `a`, an atom `b`, and a noun `c`, producing the list of `a` with the item at index `b` replaced with `c`.

#### Accepts

`a` is a list.

`b` is a atom.

`c` is a noun.

#### Produces

the list of `a` with the item at index `b` replaced with `c`.

#### Source

```    ++  snap
|*  [a/(list) b/@ c/*]
^+  a
(weld (scag b a) [c (slag +(b) a)])
```

#### Examples

```    > (snap (limo ~[2 3 4]) 1 11)
~[2 11 4]
```

### `++into`

Insert item at index

Accepts a `list` `a`, an atom `b`, and a noun `c`, producing the list of `a` with the item `c` inserted at index `b`.

#### Accepts

`a` is a list.

`b` is a atom.

`c` is a noun.

#### Produces

the list of `a` with the item `c` inserted at index `b`.

#### Source

```    ++  into
|*  [a/(list) b/@ c/*]
^+  a
(weld (scag b a) [c (slag b a)])
```

#### Examples

```    > (into (limo ~[2 3 4]) 1 11)
~[2 11 3 4]
```

### `++sort`

Quicksort

Quicksort: accepts a `++list` `a` and a gate `b` which accepts two nouns and produces a flag. `++sort` then produces a list of the elements of `a`, sorted according to `b`.

#### Accepts

`a` is a list.

`b` is a gate that accepts two nouns and produces a boolean.

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

```        > (sort `(list @)`[0 1 2 3 ~] gth)
~[3 2 1 0]
```

### `++spin`

Gate to list, with state

Accepts a `++list` `a`, some state `b`, and a gate `c`. `c` is called with a tuple -- the head is an element of `a` and the tail is the state `b`, and should produce a tuple of the transformed element and the (potentially modified) state `b`. Produces a pair where the first element is a list of the transformed elements of `a`, and the second element is the final value of `b`.

#### Accepts

`a` is a `++list`.

`b` is a noun.

`c` is a gate.

#### Produces

A pair of a list and a noun.

#### Source

```    ++  spin
~/ %spin
|* [a=(list) b=* c=_|=(^ [** +<+])]
=> .(c `\$-([_?>(?=(^ a) i.a) _b] [_-:(c) _b])`c)
=/ acc=(list _-:(c)) ~
|- ^- (pair _acc _b)
?~  a
[(flop acc) b]
=^ res b (c i.a b)
\$(acc [res acc], a t.a)
```

#### Examples

```    > %^  spin  (limo ~[4 5 6])         ::  Trivial example -- does nothing with the state
0
|=([n=@ a=@] [n a])
[p=~[4 5 6] q=0]

> %^  spin  (limo ~[4 5 6])         ::  Form a pair with `p` as the index and `q` as the list element
0
|=([n=@ a=@] [`(pair)`[a n] +(a)])
[p=~[[p=0 q=4] [p=1 q=5] [p=2 q=6]] q=3]

> %^  spin  (reap 10 0)             :: Create 10 random numbers less than `10`
~(. og eny)
[p=~[7 8 6 0 1 5 4 7 9 3] q=<4.rvi {a/@uvJ <51.qyl 129.pdd 41.mac 1.ane \$141>}>]
```

#### Discussion

`(~(rads og eny) 2)` creates a random number less than `2`, seeding the RNG with entropy (`eny`). The head of the product is the random number, the tail is the continuation of the RNG.

### `++spun`

Gate to list, with state

Accepts a `list` `a` and a gate `b`. `c` is internal state, initially derived by bunting the tail of the sample of gate `b`, instead of being passed in explicitly as in `++spin`. Produces a list with the gate applied to each element of the original list. `b` is called with a tuple -- the head is an element of `a` and the tail is the state `c`, and should produce a tuple of the transformed element and the (potentially modified) state `c`.

#### Accepts

`a` is a `++list`.

`b` is a gate.

A list.

#### Source

```    ++  spun
~/ %spun
|* [a=(list) b=_|=(^ [** +<+])]
p:(spin a +<+.b b)
```

#### Examples

```    > %+  spun  (limo ~[4 5 6])            ::  `p` as the index and `q` as the list element
|=([n=@ a=@] [`(pair)`[a n] +(a)])
~[[p=0 q=4] [p=1 q=5] [p=2 q=6]]

> =l (limo ~[7 8 9])
> %+  spun  (limo ~[4 5 6])            ::  joins two lists into a list of pairs
|=([n=@ a=@] [`(pair)`[(snag a l) n] +(a)])
~[[p=7 q=4] [p=8 q=5] [p=9 q=6]]
```

### `++swag`

Infix

Similar to `substr` in Javascript: extracts a string infix, beginning at inclusive index `a`, producing `b` number of characters.

#### Accepts

`a` is an atom.

`b` is an atom.

`c` is a list.

#### Produces

A list of the same type as `c`.

#### Source

```    ++  swag
|*  [[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

`a` is a list.

`b` is a gate.

A list.

#### Source

```    ++  turn
~/  %turn
|*  [a=(list) b=gate]
|-
?~  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]
```

#### Discussion

`turn` is Hoon's version of 'map' in Haskell.

### `++weld`

Concatenate

Concatenate two `++list`s `a` and `b`.

#### Accepts

`a` and `b` are lists.

#### Source

```    ++  weld
~/  %weld
|*  [a=(list) b=(list)]
=>  .(a ^.(homo a), b ^.(homo b))
|-  ^+  b
?~  a  b
[i.a \$(a t.a)]
```

#### Examples

```    > (weld "urb" "it")
"urbit"

> (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.

A list.

#### Source

```    ++  welp
=|  [* *]
|%
+-  \$
?~  +<-
+<-(. +<+)
+<-(+ \$(+<- +<->))
--
```

#### Examples

```    > (welp "foo" "bar")
"foobar"

> (welp ~[60 61 62] ~[%a %b %c])
[60 61 62 %a %b %c ~]

> ? (welp ~[60 61 62] ~[%a %b %c])
{@ud @ud @ud \$a \$b \$c \$~}
[60 61 62 %a %b %c ~]

> (welp [sa+1 so+2 ~] si=3)
[[%sa 1] [%so 2] si=3]
```

### `++zing`

Turns a `++list` of lists into a single list by promoting the elements of each sublist into the higher.

A list of lists.

A list.

#### Source

```    ++  zing
=|  *
|%
+-  \$
?~  +<
+<
(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]
```