# `PtcRunner.Lisp.Runtime.Collection`
[🔗](https://github.com/andreasronge/ptc_runner/blob/main/lib/ptc_runner/lisp/runtime/collection.ex#L1)

Collection operations for PTC-Lisp runtime.

Provides filtering, mapping, sorting, and other collection manipulation functions.

Selection operations (filter, remove, find, some, every?, not_any?,
take_while, drop_while) are implemented in `Collection.Select`.

Transformation operations (map, mapv, mapcat, keep, map_indexed)
are implemented in `Collection.Transform`.

# `avg`

# `avg_by`

# `butlast`

# `combinations`

Generate all n-combinations from a collection.

Works with any seqable: lists, strings, maps.

## Examples

    iex> PtcRunner.Lisp.Runtime.Collection.combinations([1, 2, 3, 4], 3)
    [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]

    iex> PtcRunner.Lisp.Runtime.Collection.combinations([1, 2], 0)
    [[]]

    iex> PtcRunner.Lisp.Runtime.Collection.combinations([1, 2], 3)
    []

# `concat2`

# `conj`

# `cons`

Returns a new seq with item prepended.

## Examples

    iex> PtcRunner.Lisp.Runtime.Collection.cons(1, [2, 3])
    [1, 2, 3]

    iex> PtcRunner.Lisp.Runtime.Collection.cons(1, nil)
    [1]

# `contains?`

# `count`

# `dedupe`

# `difference`

# `distinct`

# `distinct_by`

# `drop`

# `drop_last`

# `drop_last`

# `drop_while`

# `empty`

Returns an empty collection of the same type, or nil for nil input.

## Examples

    iex> PtcRunner.Lisp.Runtime.Collection.empty([1, 2, 3])
    []

    iex> PtcRunner.Lisp.Runtime.Collection.empty(%{a: 1})
    %{}

# `empty?`

# `every?`

# `ffirst`

# `filter`

# `filterv`

Like filter but always returns a vector. In PTC-Lisp, this is
equivalent to filter since all sequences are vectors.

# `find`

# `first`

# `flatten`

# `fnext`

# `frequencies`

# `group_by`

# `hash_set`

# `interleave_variadic`

Variadic `interleave` over seqables (Clojure's 0/1/n arity).

Each argument is coerced through `interleave_seq/1`: lists pass through,
strings become their graphemes (GAP-S98), and `nil` becomes `[]` (GAP-S20) —
matching the `interpose` sibling and Clojure. Direct maps/sets have no clause
and raise, surfaced as a `type_error` (DIV-29: positional ops require an
explicit ordered view via `seq`/`entries`/`keys`/`vals`).

Zero args yield `[]`; a single seqable is returned as its own seq; multiple
seqables are interleaved, stopping at the shortest.

## Examples

    iex> PtcRunner.Lisp.Runtime.Collection.interleave_variadic([])
    []

    iex> PtcRunner.Lisp.Runtime.Collection.interleave_variadic([[1, 2]])
    [1, 2]

    iex> PtcRunner.Lisp.Runtime.Collection.interleave_variadic([[1, 2], [3, 4], [5, 6]])
    [1, 3, 5, 2, 4, 6]

    iex> PtcRunner.Lisp.Runtime.Collection.interleave_variadic(["ab", [1, 2]])
    ["a", 1, "b", 2]

    iex> PtcRunner.Lisp.Runtime.Collection.interleave_variadic([nil, [1]])
    []

# `interpose`

Returns a list with sep inserted between each element.

## Examples

    iex> PtcRunner.Lisp.Runtime.Collection.interpose(", ", ["a", "b", "c"])
    ["a", ", ", "b", ", ", "c"]

    iex> PtcRunner.Lisp.Runtime.Collection.interpose(:x, [1])
    [1]

    iex> PtcRunner.Lisp.Runtime.Collection.interpose(:x, [])
    []

    iex> PtcRunner.Lisp.Runtime.Collection.interpose(:x, nil)
    []

    iex> PtcRunner.Lisp.Runtime.Collection.interpose(nil, [1, 2, 3])
    [1, nil, 2, nil, 3]

    iex> PtcRunner.Lisp.Runtime.Collection.interpose(",", "ab")
    ["a", ",", "b"]

# `intersection`

# `into`

# `keep`

# `keep_indexed`

# `last`

# `map`

# `map`

# `map`

# `map_indexed`

# `mapcat`

# `mapv`

# `mapv`

# `mapv`

# `max_by`

# `max_by_variadic`

Variadic version of max-by that supports both (max-by key coll)
and (apply max-by key item1 item2 ...).

# `max_key_variadic`

Returns the x for which (f x) is greatest. Matches Clojure's max-key.

## Examples

    iex> PtcRunner.Lisp.Runtime.Collection.max_key_variadic([&String.length/1, "a", "abc", "ab"])
    "abc"

# `min_by`

# `min_by_variadic`

Variadic version of min-by that supports both (min-by key coll)
and (apply min-by key item1 item2 ...).

# `min_key_variadic`

Returns the x for which (f x) is least. Matches Clojure's min-key.

## Examples

    iex> PtcRunner.Lisp.Runtime.Collection.min_key_variadic([&String.length/1, "a", "abc", "ab"])
    "a"

# `next`

# `nfirst`

# `nnext`

# `not_any?`

# `not_empty`

# `not_every?`

# `nth`

# `nth`

# `nthnext`

# `nthrest`

# `partition`

# `partition`

# `partition`

# `partition_all`

# `partition_all`

# `partition_by`

# `peek`

Returns the last element of a vector without removing it.
Returns nil for nil or empty collections.

## Examples

    iex> PtcRunner.Lisp.Runtime.Collection.peek([1, 2, 3])
    3

    iex> PtcRunner.Lisp.Runtime.Collection.peek([])
    nil

# `pop`

Returns the collection without the last element.
Returns nil for nil. Returns nil for empty collections.

## Examples

    iex> PtcRunner.Lisp.Runtime.Collection.pop([1, 2, 3])
    [1, 2]

    iex> PtcRunner.Lisp.Runtime.Collection.pop([])
    nil

# `postwalk`

Transform a tree bottom-up by applying f to each node after recursing into children.

## Examples

    iex> PtcRunner.Lisp.Runtime.Collection.postwalk(&Function.identity/1, [1, [2, 3]])
    [1, [2, 3]]

# `prewalk`

Transform a tree top-down by applying f to each node before recursing into children.

## Examples

    iex> PtcRunner.Lisp.Runtime.Collection.prewalk(&Function.identity/1, [1, [2, 3]])
    [1, [2, 3]]

# `range`

# `range`

# `range`

# `reduce`

# `reduce`

# `remove`

# `replace_coll`

Clojure's `clojure.core/replace` seq form: replace each element of `coll`
with its lookup in `smap` (a map or an indexable vector), leaving elements
absent from `smap` unchanged.

`coll` is normalized as a seq, so any seqable (list, vector, string, map,
set, or nil) is accepted and an empty/`nil` input yields `[]`. Flexible
lookup is used so PTC's keyword/string key normalization matches keyword
elements, and a vector `smap` resolves elements as 0-based indexes.

Lookup follows PTC's `get` value model: a list-valued element is treated as a
get-in path, not an exact key, so vector map keys are not matched (consistent
with `(get {[:a] :x} [:a])` => nil) — a deliberate divergence from Clojure's
exact map-entry lookup.

## Examples

    iex> PtcRunner.Lisp.Runtime.Collection.replace_coll(%{"a" => :x}, [:a, :b])
    [:x, :b]

    iex> PtcRunner.Lisp.Runtime.Collection.replace_coll([10, 20, 30], [0, 1, 2, 0])
    [10, 20, 30, 10]

    iex> PtcRunner.Lisp.Runtime.Collection.replace_coll([10, 20, 30], [5])
    [5]

    iex> PtcRunner.Lisp.Runtime.Collection.replace_coll(%{}, nil)
    []

# `rest`

# `reverse`

# `second`

# `seq`

# `some`

# `sort`

# `sort`

# `sort_by`

# `sort_by`

# `split_at`

# `split_with`

# `subvec`

Returns a subvector from start (inclusive) to end (exclusive).
Clamps indices to valid range.

## Examples

    iex> PtcRunner.Lisp.Runtime.Collection.subvec([0, 1, 2, 3, 4], 1, 3)
    [1, 2]

    iex> PtcRunner.Lisp.Runtime.Collection.subvec([0, 1, 2, 3, 4], 2)
    [2, 3, 4]

# `subvec`

# `sum`

# `sum_by`

# `take`

# `take_last`

# `take_while`

# `tree_seq`

Returns a depth-first lazy sequence of all nodes in a tree.

branch? is a predicate that returns true if a node has children.
children returns the children of a branch node.

When branch? or children is a keyword, it is used to access that key from maps.
For branch?, the result is checked for truthiness.

## Examples

    iex> tree = %{id: 1, children: [%{id: 2, children: []}, %{id: 3, children: []}]}
    iex> result = PtcRunner.Lisp.Runtime.Collection.tree_seq(
    ...>   fn node -> is_map(node) && Map.has_key?(node, :children) end,
    ...>   fn node -> Map.get(node, :children, []) end,
    ...>   tree
    ...> )
    iex> Enum.map(result, & &1.id)
    [1, 2, 3]

# `union`

# `walk`

Generic tree walker. Applies inner to each element of form, then applies outer to the result.

For lists, walks each element. For maps, walks each [key, value] pair.
For sets, walks each element and reconstructs the set.
For scalars, just applies outer.

## Examples

    iex> PtcRunner.Lisp.Runtime.Collection.walk(&Function.identity/1, &Function.identity/1, [1, 2, 3])
    [1, 2, 3]

    iex> PtcRunner.Lisp.Runtime.Collection.walk(&Function.identity/1, &Enum.sum/1, [1, 2, 3])
    6

# `zip`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
