PtcRunner.Lisp.Runtime.Collection (PtcRunner v0.12.0)

Copy Markdown View Source

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.

Summary

Functions

Generate all n-combinations from a collection.

Returns a new seq with item prepended.

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

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

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

Returns a list with sep inserted between each element.

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

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

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

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

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

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

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

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

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.

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

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

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

Functions

avg(coll)

avg_by(key, coll)

butlast(coll)

combinations(coll, n)

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(a, b)

conj(list, x)

cons(x, coll)

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?(set, val)

count(set)

dedupe(coll)

difference(s1, s2)

distinct(coll)

distinct_by(key, coll)

drop(n, coll)

drop_last(coll)

drop_last(n, coll)

drop_while(pred, coll)

See PtcRunner.Lisp.Runtime.Collection.Select.drop_while/2.

empty(coll)

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?(set)

every?(pred, coll)

See PtcRunner.Lisp.Runtime.Collection.Select.every?/2.

ffirst(coll)

filter(pred, coll)

See PtcRunner.Lisp.Runtime.Collection.Select.filter/2.

filterv(pred, coll)

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

find(coll, key)

See PtcRunner.Lisp.Runtime.Collection.Select.find/2.

first(coll)

flatten(coll)

fnext(coll)

frequencies(coll)

group_by(key, coll)

hash_set(args)

interleave_variadic(colls)

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(sep, coll)

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(s1, s2)

into(to, from)

keep(f, coll)

See PtcRunner.Lisp.Runtime.Collection.Transform.keep/2.

keep_indexed(f, coll)

See PtcRunner.Lisp.Runtime.Collection.Transform.keep_indexed/2.

last(coll)

map(f, coll)

See PtcRunner.Lisp.Runtime.Collection.Transform.map/2.

map(f, c1, c2)

See PtcRunner.Lisp.Runtime.Collection.Transform.map/3.

map(f, c1, c2, c3)

See PtcRunner.Lisp.Runtime.Collection.Transform.map/4.

map_indexed(f, coll)

See PtcRunner.Lisp.Runtime.Collection.Transform.map_indexed/2.

mapcat(f, coll)

See PtcRunner.Lisp.Runtime.Collection.Transform.mapcat/2.

mapv(f, coll)

See PtcRunner.Lisp.Runtime.Collection.Transform.mapv/2.

mapv(f, c1, c2)

See PtcRunner.Lisp.Runtime.Collection.Transform.mapv/3.

mapv(f, c1, c2, c3)

See PtcRunner.Lisp.Runtime.Collection.Transform.mapv/4.

max_by(key, coll)

max_by_variadic(arg1)

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

max_key_variadic(list)

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(key, coll)

min_by_variadic(arg1)

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

min_key_variadic(list)

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(coll)

nfirst(coll)

nnext(coll)

not_any?(pred, coll)

See PtcRunner.Lisp.Runtime.Collection.Select.not_any?/2.

not_empty(coll)

not_every?(pred, coll)

See PtcRunner.Lisp.Runtime.Collection.Select.not_every?/2.

nth(coll, idx)

nth(coll, idx, default)

nthnext(coll, n)

nthrest(coll, n)

partition(n, coll)

partition(n, step, coll)

partition(n, step, pad, coll)

partition_all(n, coll)

partition_all(n, step, coll)

partition_by(f, coll)

peek(coll)

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(coll)

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(f, form)

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(f, form)

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(end_val)

range(start, end_val)

range(start, end_val, step)

reduce(f, coll)

reduce(f, init, coll)

remove(pred, coll)

See PtcRunner.Lisp.Runtime.Collection.Select.remove/2.

replace_coll(smap, 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(coll)

reverse(coll)

second(coll)

seq(coll)

some(pred, coll)

See PtcRunner.Lisp.Runtime.Collection.Select.some/2.

sort(coll)

sort(comp, coll)

sort_by(key, coll)

sort_by(key, comp, coll)

split_at(n, coll)

split_with(pred, coll)

subvec(coll, start)

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(coll, start, end_idx)

sum(coll)

sum_by(key, coll)

take(n, coll)

take_last(n, coll)

take_while(pred, coll)

See PtcRunner.Lisp.Runtime.Collection.Select.take_while/2.

tree_seq(branch?, children, root)

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(s1, s2)

walk(inner, outer, form)

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(c1, c2)