Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Collections

Collections are immutable values: every method returns a new collection. List doubles as a deque, Map and Set are ordered, and HashMap and HashSet are persistent hash tries that print in key order. Build empty ones with empty_map(), empty_set(), empty_heap(), hash_map(), hash_set() and bits(n), or convert a list with to_set, to_heap, to_hash_set, to_hash_map and to_bits(n). empty_flat_map() and xs.to_flat_map (pairs, the last value per key wins) make a FlatMap, and mdspan(xs, shape) views a list as a row-major array. A View comes from xs.view, iota(a, b) (a up to b, exclusive) or iterate(x, f, n) (x, f(x), … n values); in native code a pipeline whose stages are visible where it is consumed runs as one fused loop.

ReceiverMethods
List[A]len is_empty map flat_map filter fold(init, (acc, x) => ..) any all find sort_by(key) sum push(x) concat(ys) take(n) drop(n) reverse sort unique contains(x) first last get(i) min max counts zip(ys) enumerate join(sep), and sort_with((a, b) => Int) binary_search(x) lower_bound(x) upper_bound(x) index_of(x) find_index(f) slice(from, to) chunks(n) windows(n) group_by(key) partition(f) scan(init, f) flatten push_front(x) pop_front pop_back take_while(f) drop_while(f) rotate(k) repeat(n) merge(ys) next_perm shuffle(seed) choice(seed) to_set to_heap to_hash_set to_hash_map to_bits(n) ([0].repeat(n) is n zeros; merge expects both lists sorted; next_perm is the next lexicographic permutation or none; to_hash_map needs a list of pairs)
Map[K, V]get(k) put(k, v) remove(k) has(k) keys values items len is_empty (immutable: put returns a new map)
Set[A]add(x) remove(x) has(x) len is_empty items union(s) inter(s) diff(s) min max (ordered; items is sorted)
Heap[A]push(x) pop peek len is_empty items (min-heap; pop gives Opt[(min, rest)]; items is sorted)
HashMap[K, V]get(k) put(k, v) remove(k) has(k) keys values items len is_empty (persistent hash trie; keys, items and display are in key order)
HashSet[A]add(x) remove(x) has(x) len is_empty items union(s) inter(s) diff(s)
Bitshas(i) set(i) clear(i) flip(i) len count union(b) inter(b) diff(b) xor(b) flip_all items (out-of-range indexes and size mismatches trap; prints as bits(8){0, 3})
FlatMap[K, V]fields keys values (sorted parallel lists); get(k) has(k) put(k, v) remove(k) len is_empty items lower_bound(k) between(lo, hi) (get, has and lower_bound are binary searches; between is the keys in lo..hi, a slice that copies nothing; put and remove copy)
MdSpan[T]fields data offset shape strides; rank size get(idx) set(idx, x) slice(dim, lo, hi) sub(i) transpose to_list (idx is a List[Int] with one index per dimension; slice keeps lo..hi of dimension dim, sub(i) fixes the first index, and neither they nor transpose copy elements; bad indexes and shapes trap)
View[A]map(f) filter(f) take(n) drop(n) take_while(f) drop_while(f) enumerate zip(v) chain(v), which are lazy, and to_list fold(init, f) len sum first find(f) any(f) all(f) and for x in v, which pull (stage functions must be pure; a view can’t be compared, encoded or printed)

Notes: first, last, get, min, max, find, index_of, find_index, binary_search and split_once return Opt. counts returns List[(A, Int)] and group_by returns List[(K, List[A])], both in first-seen order. words splits on non-alphanumeric characters. sort_by takes a key function (a tuple key sorts by several fields; negate a number to sort descending); sort_with takes a comparator returning a negative, zero or positive Int, and is stable. binary_search and lower_bound expect a sorted list. Str indexes (index_of, pad_left widths) count characters, and padding repeats fill to exactly n characters. to_f64 accepts [+-]digits[.digits][e[+-]digits] after trimming. scan returns the accumulator after each element. repeat(n) is the list n times over, and traps when n < 0. pop_front and pop_back give Opt[(x, rest)], and List doubles as a deque: push, push_front, pop_front and pop_back are amortized O(1) in native code. The interpreter appends in place (push, concat, StrBuf.add, Map.put, Set.add, remove) when the receiver is a local variable’s last use, as in xs := xs.push(x) or a fold’s accumulator, so building a list or string one item at a time is linear in both tiers (the playground, which keeps its code small, copies). Random numbers are pure: each call returns (value, next_seed); rand is non-negative, rand_int is in lo..hi (traps unless lo < hi), rand_f64 is in [0, 1). Collections are immutable values. Set prints as {1, 2} and Heap as heap[1, 2]. rand_normal uses Box-Muller on two draws; shuffle is Fisher-Yates; all are pure in the seed.

range(a, b, step) pipelines (.map, .filter, .sum, .len) and for x in range(...) run natively without building the list; for loops over ranges are lazy in both tiers.

Pure map and filter pipelines over large lists run across cores in native code; see Concurrency.