Collections
Arr[T] and Map[K, V] arrive through the prelude. Both are implemented in KataScript. Use direct bindings when growing or mutating them; their current storage and lifetime behavior has known limits.
Arrays
Section titled “Arrays”[value, ...] creates an array and infers the element type. Elements must be compatible. To construct an empty array of a known type, use Arr[T].new().
let values = Arr[Int].new()values.push(10)values.push(20)values[0] = 11print(values.len)print(values.get(0).unwrap_or(0))print(values.pop().unwrap_or(0))| Operation | Contract |
|---|---|
Arr[T].new() | Create an empty array of T |
array.len | Number of live elements; a field, with no parentheses |
array.push(value) | Append a value of the element type |
array.pop() | Remove the last value; return Opt[T], absent if empty |
array.get(index) | Return Opt[T], absent if the index is out of bounds |
array.set(index, value) | Replace an existing element; return whether it existed |
Array indices are zero-based Int values. Negative indices are out of bounds; they do not count backward from the end. set does not append.
Map[K, V].new() creates an empty map with explicit key and value types. There is no map literal. Keys need hashing and equality behavior; the examples use Str keys.
let scores = Map[Str, Int].new()scores.set("Ada", 42)scores["Lin"] = 37print(scores.has("Ada"))print(scores.get("Sam").unwrap_or(0))print(scores.len())| Operation | Contract |
|---|---|
map.set(key, value) | Insert a new key or replace its value |
map.get(key) | Return Opt[V], absent when the key is missing |
map.has(key) | Return whether the key exists |
map.del(key) | Remove a key; return whether it existed |
map.len() | Number of entries; a method, with parentheses |
Repeated insertion/deletion has a known corruption defect, and float keys have equality/hash edge cases. The documented examples avoid both patterns.
Indexing
Section titled “Indexing”collection[key] invokes GetItem through get_item. collection[key] = value invokes SetItem through set_item. Array indexing assumes the position exists; map indexing assumes the key exists. A failed read stops evaluation. Use get(...).unwrap_or(default) or match when absence is expected.
Array assignment replaces an existing element. Map assignment inserts or replaces an entry. Bin also supports read indexing and returns a Byte. Tuples use positional access such as tuple.0, rather than the collection indexing protocol.
Iteration
Section titled “Iteration”for pattern in collection { ... } obtains an iterator through to_iter() when available, then calls next() until it returns Opt[T].Non. Each Opt[T].Val(value) produces one loop iteration. Arrays yield elements; maps yield (key, value) tuples.
let scores = Map[Str, Int].new()scores["Ada"] = 42scores["Lin"] = 37let total = 0for (_, score) in scores { total = total + score }print(total)Map order is not a stable output contract. Traverse a separate sequence of keys when ordering matters. Do not mutate a collection while iterating over it. A custom iterable implements ToIter[T], and its iterator implements Iter[T]; see the custom iterator example.
Shared method names
Section titled “Shared method names”Method help is name-based. A name does not establish a particular receiver type: get can mean an array position or map key, and user types can define their own method with the same name. new() is a library convention for static constructors, not a keyword. len is especially easy to confuse: arrays expose a field, while strings, binary values, tuples, and maps expose methods.
Assigning a collection to another name does not promise a deep copy. Keep one binding responsible for growth and avoid treating Copy or Dupe as a completed ownership guarantee.