# Lists

`List → Object`

Lists are immutable vectors of arbitrary values.

Example:

```[1, \$b, "three", 4.0]
[]```
```l length → Integer
| l is-a?: List```

Returns the length of the list `l`.

Example:

```> [1, 2, 3] length
3
```
```l empty? → Boolean
| l is-a?: List```

Is the list `l` empty?

Example:

```> [] empty?
True
> [1, 2, 3] empty?
False
```
```l at: index → any
| l is-a?: List
| index is-a?: Integer```

Returns the list's value at `index`. If the index is out of bounds, `@(out-of-bounds: index for-list: l)` is raised.

Example:

```> [1, 2, 3] at: 1
2
> [1, 2, 3] at: 3
ERROR: <error @(out-of-bounds: 3 for-list: [1, 2, 3])>
```
```l at: index put: v → List
| l is-a?: List
| index is-a?: Integer```

Yield a new list with the value at `index` replaced with `v`. If the index is out of bounds, `@(out-of-bounds: index for-list: l)` is raised.

Example:

```> [1, 2, 3] at: 1 put: 5
[1, 5, 3]
```
```l head → any
| l is-a?: List```

Returns the first value of the list. If the list is empty, `@empty-list` is raised.

Example:

```> [1, 2, 3] head
1
```
```l last → any
| l is-a?: List```

Returns the last value of the list. If the list is empty, `@empty-list` is raised.

Example:

```> [1, 2, 3] last
3
```
```l init → List
| l is-a?: List```

Returns all but the last value of the list. If the list is empty, `@empty-list` is raised.

Example:

```> [1, 2, 3] init
[1, 2]
```
```l tail → List
| l is-a?: List```

Returns all but the first value of the list. If the list is empty, `@empty-list` is raised.

Example:

```> [1, 2, 3] tail
[2, 3]
```
```l from: start to: end → List
| l is-a?: List
| start is-a?: Integer
| end is-a?: Integer```

Returns the slice of elements from `start` to `end` of `l`. If the range is invalid, `@(invalid-range: @(from: start to: end) for-list: l)` is raised. A range is invalid if either `start` or `end` are negative, or if either are out of the list's boundaries.

Example:

```> [1, 2, 3, 4, 5] from: 1 to: 3
[2, 3]
```
```l take: n → List
| l is-a?: List
| n is-a?: Integer```

Returns a list of the first `n` values of the list. If `n` is greater than the list's length, it returns as many as it can (i.e., the entire list); the length of the returned list will not always be `n`.

Example:

```> [1, 2, 3, 4, 5] take: 2
[1, 2]
> [1, 2] take: 4
[1, 2]
```
```l drop: n → List
| l is-a?: List
| n is-a?: Integer```

Returns a list of the values after `n` values have been dropped from the start of the list. If `n` is greater than the list's length, it returns an empty list.

Example:

```> [1, 2, 3, 4, 5] drop: 2
[3, 4, 5]
> [5, 6, 7] drop: 5
[]
```
```v replicate: n → List
| n is-a?: Integer```

Returns a list containing `v` replicated `n` times.

Example:

```> "Odelay!" replicate: 5
["Odelay!", "Odelay!", "Odelay!", "Odelay!", "Odelay!"]
```
```x . xs → List
| xs is-a?: List```

List constructor; yield a new list with `x` added to the front of `xs`.

Example:

```> 1 . []

> 1 . [2, 3]
[1, 2, 3]
```
```a .. b → List
| a is-a?: List
| b is-a?: List```

Appends the two lists `a` and `b`, returning a new list.

Example:

```> [1, 2, 3] .. [4, 5, 6]
[1, 2, 3, 4, 5, 6]
> [] .. [1, 2] .. []
[1, 2]
```
```l reverse → List
| l is-a?: List```

Returns a new list, with all values of `l`, in reversed order.

Example:

```> [1, 2, 3] reverse
[3, 2, 1]
```
```l map: a → List
| l is-a?: List
| a responds-to?: @call:```

Returns a new list, with `call:` sent to `a` with each value in `l`.

Example:

```> [1, 2, 3] map: { n | n + 1 }
[2, 3, 4]
> [1, 2, 3] map: @(* 2)
[2, 4, 6]
```
```x zip: (... ys) &zipper: @id → List
| x is-a?: List
| zipper responds-to?: @call:```

"Zips" up the lists `x` and `ys`. If `zipper` is not `@id`, it is `call:`ed with each zipped value as an argument.

The list it returns is as long as the shortest list.

Example:

```> [1, 2, 3] zip: [4, 5, 6] &zipper: @*
[4, 10, 18]
> [1, 2, 3] zip: (["a", "b", "c"], [\$a, \$b, \$c])
[[1, "a", \$a], [2, "b", \$b], [3, "c", \$c]]
> [1, 2, 3] zip: (["a", "b", "c"], [\$a, \$b, \$c]) &zipper: { a b c | a -> b -> c }
[1 -> ("a" -> \$a), 2 -> ("b" -> \$b), 3 -> ("c" -> \$c)]
```
```l take-while: p → List
| l is-a?: List
| p responds-to?: @call:```

Takes values from list `l` while `p` called on them yields `True`.

Example:

```> [1, 3, 4, 5, 6] take-while: @odd?
[1, 3]
```
```l drop-while: p → List
| l is-a?: List
| p responds-to?: @call:```

Removes values from list `l` while `p` called on them yields `True`, returning a list of the remaining values.

Example:

```> [1, 3, 4, 5, 6] drop-while: @odd?
[4, 5, 6]
```
```l filter: p → List
| l is-a?: List
| p responds-to?: @call:```

Returns a list of all values in `l` that satisfy the predicate `p`.

Example:

```> [1, 2, 3, 4, 5] filter: @odd?
[1, 3, 5]
> [1, 2, 3, 2, 1] filter: { n | n == 3 }

```
```l reduce: b → any
| l is-a?: List
| b responds-to?: @call:```

Alias for `l tail reduce: b with: l head`. If the list is empty, `@empty-list` is raised.

Example:

```> [1, 2, 3, 4, 5] reduce: @*
120
```
```l reduce: b with: v → any
| l is-a?: List
| b responds-to?: @call:```

Reduces the list to a single value by "folding" over it, with `v` as the initial value.

Example:

```> [1, 2, 3, 4, 5] reduce: @*
120
> [] reduce: @* with: 1
1
```
```l reduce-right: b → any
| l is-a?: List
| b responds-to?: @call:```

Similar to `reduce:`, but right-associative. If the list is empty, `@empty-list` is raised.

```l reduce-right: b with: v → any
| l is-a?: List
| b responds-to?: @call:```

Similar to `reduce:with:`, but right-associative.

```l concat → List
| l is-a?: List```

Reduces a list by appending all of its values. The list's values must all be lists.

Example:

```> [[1, 2], [3, 4, 5], ] concat
[1, 2, 3, 4, 5, 6]
> [] concat
[]
```
```l sum → any
| l is-a?: List```

Reduces a list with `+` and `0`.

Example:

```> [1, 2, 3] sum
6
> [] sum
0
```
```l product → any
| l is-a?: List```

Reduces a list with `*` and `1`.

Example:

```> [1, 2, 3] product
6
> [] product
1
```
```l maximum → any
| l is-a?: List```

Reduces a list with `max:`. The list must not be empty.

Example:

```> [1, 2, 3] maximum
3
```
```l minimum → any
| l is-a?: List```

Reduces a list with `min:`. The list must not be empty.

Example:

```> [1, 2, 3] minimum
1
```
```l all?: p → Boolean
| l is-a?: List
| p responds-to?: @call:```

Checks if all values in `l` satisfy the predicate `p`.

Example:

```> [1, 3, 5] all?: @odd?
True
> [1, 3, 6] all?: @odd?
False
> [] all?: @odd?
True
```
```l any?: p → Boolean
| l is-a?: List
| p responds-to?: @call:```

Checks if any values in `l` satisfy the predicate `p`.

Example:

```> [2, 3, 6] any?: @odd?
True
> [2, 4, 6] any?: @odd?
False
> [] any?: @odd?
False
```
```l and → Boolean
| l is-a?: List```

Check if all values in the list are `True`.

Example:

```> [1 == 1, \$a == \$a] and
True
> [1 == 1, \$a == \$b] and
False
> [] and
True
```
```l or → Boolean
| l is-a?: List```

Check if any values in the list are `True`.

Example:

```> [1 == 1, \$a == \$a] or
True
> [1 == 1, \$a == \$b] or
True
> [1 == 2, \$a == \$c] or
False
> [] or
False
```
```l contains?: v → Boolean
| l is-a?: List```

Check if `v` is a member of the list `l`.

Example:

```> "abc" contains?: \$a
True
> "abc" contains?: \$d
False
```
```v in?: l → Boolean
| l is-a?: List```

Alias for `l contains?: v`.

```l push: v → List
| l is-a?: List```

Yields a new list with `v` added to the end of `l`.

Example:

```> [1, 2, 3] push: 4
[1, 2, 3, 4]
```
```l cons: v → List
| l is-a?: List```

See `.`.

`a << b → is-a?: a`

A macro for `push:` with destructive update.

Example:

```> a = [1, 2, 3]
[1, 2, 3]
> a << 4
[1, 2, 3, 4]
> a
[1, 2, 3, 4]
> '(a << 5) expand
'(a = a push: 5)
```
`a >> b → is-a?: b`

A macro for `cons:` with destructive update.

Example:

```> a = [1, 2, 3]
[1, 2, 3]
> 0 >> a
[0, 1, 2, 3]
> a
[0, 1, 2, 3]
> '(-1 >> a) expand
'(a = a cons: -1)
```
```l split: delimiter → List
| l is-a?: List
| delimiter is-a?: List```

Split a list into sublists, separated by `delimiter`. Note that strict equality (i.e. `equals?:`) is used for matching the delimiter.

Example:

```> [0, 1, 1, 2, 1, 1, 3] split: [1, 1]
[, , ]
> [0, 1, 1] split: [1, 1]
[, []]
> [] split: [1, 1]
[[]]
```
```l split-on: o → List
| l is-a?: List```

Split `l` into sublists, breaking on every occurrence of `o`. Also uses strict equality.

Example:

```> [0, 1, 2, 1, 3] split-on: 1
[, , ]
> [0, 1] split-on: 1
[, []]
> [] split-on: 1
[[]]
```
```l sort → List
| l is-a?: List```

Returns a sorted list of `l`'s values, using the mergesort algorithm. It does this by sending `>` to determine the larger between two values.

Example:

```> [1, 6, 3, 0, 10] sort
[0, 1, 3, 6, 10]
> [\$z, \$f, \$x] sort
[\$f, \$x, \$z]
```
```l sort-by: compare → List
| l is-a?: List
| compare responds-to?: @call:```

Returns a sorted list of `l`'s values, using the mergesort algorithm. `compare`, when `call:`ed with two values in `l`, should return `True` if the first is greater than the second, and `False` otherwise.

Example:

```> [1, 6, 3, 0, 10] sort-by: @>
ERROR: <error @(particle-needed: 2 given: 1)>
> [1, 6, 3, 0, 10] sort-by: @<
ERROR: <error @(particle-needed: 2 given: 1)>
```