# List Prototype

The list prototype (\$list_proto) defines verbs that perform operations on the receiver, which will be of type LIST. All verbs are of the general form:

````any list:verb(...)`
```

Where list may be a list literal or an expression returning a list value.

````LIST list:setadd(value)`
```

Returns a copy of list with value added. Only adds the value if it is not already an element of the list; the list is thus treated as a mathematical set. The value is added at the end of the resulting list.

````{1, 2, 3}:setadd(3)        => {1, 2, 3}`
`{1, 2, 3}:setadd(4)        => {1, 2, 3, 4}`
```

### setremove

````LIST list:setremove(value)`
```

Returns a copy of list with value removed. If the value appears more than once in the list, only the first occurrence is removed in the returned copy.

````{1, 2, 3}:setremove(3)        => {1, 2}`
`{1, 2, 3}:setremove(4)        => {1, 2, 3}`
```

### union

````LIST list:union(LIST other)`
```

Returns a set constructed from the union of the elements in list and other.

````{1, 2, 3}:union({1, 4})      => {1, 2, 3, 4}`
```

### intersection

````LIST list:intersection(LIST other)`
```

Returns a set constructed from the intersection of the elements in list and other.

````{1, 2, 3}:intersection({1, 4})      => {1}`
```

### difference

````LIST list:difference(LIST other)`
```

Returns a set constructed from the elements in list that are not in other.

````{1, 2, 3}:difference({1, 4})      => {2, 3}`
```

### join

````STR list:join([STR separator])`
```

Returns a string constructed from the elements in list coverted to strings and joined by copies of separator. If a separator is not specified it defaults to a single space character.

````{1, 2, 3}:join("-")      => "1-2-3"`
`{1, 2, 3}:join()         => "1 2 3"`
```

### sort

````LIST list:sort()`
```

Returns a copy of list with the elements sorted. Tries to pick the best algorithm based on the size of the list (which is currently always an insertion sort).

````{4, 2, 3, 1}:sort()         => {1, 2, 3, 4}`
```

### reverse

````LIST list:reverse()`
```

Returns a copy of list with the elements reversed.

````{4, 3, 2, 1}:reverse()      => {1, 2, 3, 4}`
```

### slice

````LIST list:slice(index, ...)`
`LIST list:slice({index, ...})`
```

Assumes list is a list of lists. Returns a list of the elements at the specified indexes of the elements of list. Note, slice() also works on lists of maps and lists of strings.

````{{"one", 1, #1}, {"two", 2, #2}, {"three", 3, #3}}:slice(2, 3)      => {{1, #1}, {2, #2}, {3, #3}}`
`{{"one", 1, #1}, {"two", 2, #2}, {"three", 3, #3}}:slice({2, 3})    => {{1, #1}, {2, #2}, {3, #3}}`
```

### flatten

````LIST list:flatten([INT depth])`
```

Returns a copy of list flattened to the specified depth. If depth is not specified, the list of fully flattened.

````{{1, 2}, {3, {4}}}:flatten()      => {1, 2, 3, 4}`
`{{1, 2}, {3, {4}}}:flatten(1)     => {1, 2, 3, {4}}`
```

### dedup unique remove_duplicates

````LIST list:dedup()`
```

Returns a copy of list with duplicate elements removed.

````{1, 2, 3, 2, 2}:dedup()     => {1, 2, 3}`
```

### compress

````LIST list:compress()`
```

Returns a copy of list with runs of duplicate elements replaced by a single element.

````{1, 2, 3, 2, 2}:compress()     => {1, 2, 3, 2}`
```

### remove_all

````LIST list:remove_all(element)`
```

Returns a copy of list with element removed.

````{1, 2, 3, 2, 2}:remove_all(2)     => {1, 3}`
```

### repeat make

````LIST list:repeat(INT number)`
```

Returns a list with list repeated number times.

````{1, 2}:repeat(2)     => {1, 2, 1, 2}`
```

### count

````INT list:count(element)`
```

Returns the number of times element appears in list.

````{1, 2, 3, 2, 2}:count(2)     => 3`
```

### is_empty is_blank

````INT list:is_empty()`
```

Returns true if list contains no elements.

````{1, 2}:is_empty()     => 0`
`{}:is_empty()         => 1`
```

### combinations

````LIST list:combinations(INT number)`
```

Returns all combinations of length number for list.

````{1, 2, 3}:combinations(1)     => {{1}, {2}, {3}}`
`{1, 2, 3}:combinations(2)     => {{1, 2}, {1, 3}, {2, 3}}`
`{1, 2, 3}:combinations(3)     => {{1, 2, 3}}`
```

### permutations

````LIST list:permutations(INT number)`
```

Returns all permutations of length number for list.

````{1, 2, 3}:permutations(1)     => {{1}, {2}, {3}}`
`{1, 2, 3}:permutations(2)     => {{1, 2}, {1, 3}, {2, 1}, {2, 3}, {3, 1}, {3, 2}}`
`{1, 2, 3}:permutations(3)     => {{1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1}}`
```

### product

````LIST list:product(LIST other)`
```

Returns the cartesian product of lists list and other.

````{1, 2, 3}:product({4, 5})     => {{1, 4}, {1, 5}, {2, 4}, {2, 5}, {3, 4}, {3, 5}}`
```

### rotate

````LIST list:rotate([INT number])`
```

Returns a copy of list which has been rotated number positions to the left (if number is positive) or right (if number is negative). If omitted, number defaults to 1.

````{1, 2, 3, 4, 5}:rotate(1)      => {2, 3, 4, 5, 1}`
`{1, 2, 3, 4, 5}:rotate(-1)     => {5, 1, 2, 3, 4}`
```

### shuffle

````LIST list:shuffle()`
```

Returns a copy of list with all elements randomly shuffled.

````{1, 2, 3, 4, 5}:shuffle()     => {3, 4, 5, 1, 2}`
`{1, 2, 3, 4, 5}:shuffle()     => {3, 1, 4, 2, 5}`
```

### sample

````LIST list:sample([INT number])`
```

Returns a list of number elements selected at random from list. If number is not specified, it defaults to 1.

````{1, 2, 3, 4, 5}:sample(2)     => {4, 5}`
`{1, 2, 3, 4, 5}:sample(3)     => {3, 1, 4}`
```

### to_map

````MAP list:to_map()`
```

Assumes list is a list of two element lists. Returns a map constructed from the elements, using the first element in the pair as the key and the second as the value.

````{{1, 2}, {3, 4}}:to_map()     => [1 -> 2, 3 -> 4]`
```

### first

````any list:first()`
```

Returns the first element of list.

````{1, 2, 3, 4, 5}:first()     => 1`
```

### last

````any list:last()`
```

Returns the last element of list.

````{1, 2, 3, 4, 5}:last()      => 5`
```