❄️ Tinsel AoC DSL

Built-in Functions & Receiver Methods Reference

This page documents every global built-in function (native VM intrinsics and std/prelude globals available in every script without an import) followed by all built-in receiver methods invoked with dot syntax (receiver.method(...)).

Note

Domain algorithms and data structures such as dijkstra, astar, bfs, dfs, toposort, union_find (std/search), orbit (std/orbit), parse_grid (std/grid), range_set (std/intervals), set (std/set), deque (std/deque), defaultdict, counter (std/collections), and memoize (std/memo) live in their respective std/* modules and are documented in the Standard Library (std/*) Reference.


Part 1: Global Built-in Functions

All functions in Part 1 are available globally in every .tin script without an import statement.

1. Output, Assertions & Debugging

Function Signature Description
println println(...values) -> nil Prints arguments separated by spaces followed by a newline \n.
print print(...values) -> nil Prints arguments separated by spaces without a trailing newline.
assert assert(cond: any, msg?: string) -> bool Panics with msg (or "assertion failed") if cond is falsy; returns true otherwise.
panic / error panic(...values) -> ! Terminates execution immediately with a formatted runtime error.
dbg / breakpoint dbg(...values) -> any Pauses execution when running under tinsel debug / tinsel run --debug and displays passed arguments; returns its first argument (or nil) so it can wrap inline expressions cleanly.
tinsel
let x = dbg(20 + 22)
assert(x == 42, "math still works")

2. File I/O, Environment & System Timing

Function / Global Signature Description
args args: [string] Global array of command-line arguments passed after the script filename.
read_file read_file(path: string) -> string Reads the entire file at path into a UTF-8 string.
read_lines read_lines(path: string) -> [string] Reads path and splits into lines (normalizing \r\n to \n).
read_sections / read_paragraphs read_sections(path: string) -> [string] Reads path and splits on blank lines (\n\n) into multi-line section blocks.
write_file write_file(path: string, content: any) -> bool Writes to_string(content) to path, creating or truncating the file.
append_file append_file(path: string, content: any) -> bool Appends to_string(content) to path, creating the file if needed.
file_exists file_exists(path: string) -> bool Returns true if a file or directory exists at path.
env env(name: string, default?: any) -> string | any Returns the value of environment variable name, or default (nil if omitted) when unset.
time_ms / now_ms time_ms() -> int Current Unix epoch wall-clock timestamp in milliseconds.
time_ns / now_ns time_ns() -> int High-resolution timestamp in nanoseconds for benchmarking.
rand rand() -> float Pseudo-random float in the half-open interval [0.0, 1.0).
rand_int rand_int(max: int) -> int / rand_int(min: int, max: int) -> int Pseudo-random integer in [0, \text{max}) or [\text{min}, \text{max}).

3. Parsing, Spatial & Collection Constructors

Function Signature Description
parse_ints parse_ints(text: string) -> [int] Regex-free byte scanner extracting all signed integers (-?\d+) from text.
lines lines(text: string) -> [string] Splits text into an array of lines (pipeline-friendly alias for text.lines()).
scan / scan_pattern scan(text: string, tmpl: string) -> [map] Extracts all non-overlapping matches of tmpl (e.g. "mul({x},{y})") from text.
vec2 vec2(x: int, y: int) -> vec2 Constructs an immutable 2D integer vector (X, Y) (packed in 64-bit Value.Num when 32-bit).
vec3 vec3(x: int, y: int, z: int) -> vec3 Constructs an immutable 3D integer vector (X, Y, Z).
Some / None Some(val: any) -> option, None: option Constructors for Tinsel's option type.
map map(entries?: [[k, v]]) -> map Creates an empty map {} or initializes one from [key, value] pairs (or map(arr, fn) when called with 2 arguments).
iter iter(source: any) -> Iter Wraps an array, range, string, Iter, or generator closure () -> Some(v) | None into a lazy Iter.
import import(path: string) -> module Dynamically loads and caches a .tin or std/* module at runtime.
tinsel
let nums = parse_ints("p=10,-20 v=-3,5")
let pos = vec2(nums[0], nums[1])
let hits = scan("mul(2,4)%&mul(5,5)", "mul({a},{b})")
assert(pos == vec2(10, -20) && hits.len() == 2 && hits[0].a == 2)

4. Mathematics, Reductions & Hashing

Function Signature Description
len len(x: any) -> int Returns the length/cardinality of an array, string, map, range, module, or custom struct.
sum sum(arr: [int | float]) -> int | float Sum of all numbers in arr (0 if empty).
min min(a, b) or min(arr: array) Smaller of two values, or minimum element of an array.
max max(a, b) or max(arr: array) Larger of two values, or maximum element of an array.
abs abs(x: int | bigint | float) -> number Absolute value $
sqrt, hypot sqrt(x) -> float, hypot(dx, dy) -> float Square root \sqrt{x} and Euclidean hypotenuse \sqrt{dx^2 + dy^2}.
floor, ceil, round floor(x) -> int, ceil(x) -> int, round(x) -> int Rounding functions from float/int to int.
sin, cos, tan, atan2 (x) -> float, atan2(y, x) -> float Trigonometric functions in radians.
log, log2, log10, exp (x) -> float Natural, base-2, base-10 logarithms, and e^x.
float_pow float_pow(base, exp) -> float Floating-point exponentiation base^{exp}.
md5 md5(text: string) -> string 32-character lowercase hexadecimal MD5 digest.
sha256 sha256(text: string) -> string 64-character lowercase hexadecimal SHA-256 digest.

5. Type Introspection & Conversion

Function Signature Description
type_of / type / typeof type_of(val: any) -> string Runtime type name ("int", "bigint", "string", "array", "vec2", "option", or struct __type__).
to_string / str to_string(val: any) -> string Canonical string representation (invokes fn to_string(self) on structs/prototypes).
to_int / int / ord to_int(val: any, base?: int) -> int Parses string in base (auto-detects 0x, 0b, 0o when base omitted), returns rune code point for char, 0/1 for bool, or truncates float.
to_bigint / bigint bigint(val: int | string | bigint, base?: int) -> bigint Converts integer or string (with optional radix base) to arbitrary-precision bigint.
to_char / char / chr to_char(code: int | string) -> char Converts Unicode code point int to char (e.g. chr(65) == 'A').
hex / to_hex hex(n: int | bigint, pad?: int) -> string Formats integer as lowercase hexadecimal, optionally zero-padded to pad width.
bin / to_bin bin(n: int | bigint, pad?: int) -> string Formats integer as binary string, optionally zero-padded to pad width.
tinsel
assert(to_int("0xFF") == 255 && to_int("1011", 2) == 11)
assert(ord('A') == 65 && chr(65) == 'A')
assert(hex(255, 4) == "00ff" && bin(5, 4) == "0101")

Part 2: Built-in Receiver Methods (receiver.method(...))

1. Universal Methods (All Composite & Primitive Types)

  • .len() -> int: Element count, rune count, range span, or custom fn len(self).
  • .type() -> string: Runtime type tag (equivalent to type_of(receiver)).
  • .to_string() -> string / .str() -> string: String representation.
  • .iter() -> Iter: Creates a lazy pull-based Iter stream over any array, range, string, or custom struct implementing fn iter(self).

2. String Methods (string)

Method Signature Description
.len() () -> int Number of Unicode runes in the string.
.ints() () -> [int] Extracts all signed integers (-?\d+) from the string.
.lines() () -> [string] Splits string by line breaks (\n, stripping \r).
.sections() / .paragraphs() / .blocks() () -> [string] Splits string on blank lines (\n\n) into multi-line blocks.
.words() () -> [string] Splits string on contiguous whitespace runs.
.split(sep?) (sep?: string) -> [string] Splits string by delimiter sep (default " "; "" splits into single-char strings).
.trim() () -> string Strips leading and trailing whitespace.
.chars() () -> [char] Returns an array of Unicode char runes.
.char_at(idx) (idx: int) -> char | nil Returns the rune at 0-based rune index idx (or nil if out of bounds).
.slice(start, end?) (start: int, end?: int) -> string Substring over rune indices [start, end) (or use s[start..end]).
.slice_from(start) (start: int) -> string Substring from start to the end of the string (or use s[start..]).
.starts_with(prefix) (prefix: string) -> bool Returns true if string begins with prefix.
.ends_with(suffix) (suffix: string) -> bool Returns true if string ends with suffix.
.contains(sub) (sub: string) -> bool Returns true if sub occurs in string (or use sub in s).
.index_of(sub) (sub: string) -> int 0-based byte index of first sub occurrence, or -1 if absent.
.replace(old, new) (old: string, new: string) -> string Replaces all non-overlapping occurrences of old with new.
.repeat(count) (count: int) -> string Repeats the string count times.
.scan(tmpl) / .scan_pattern(tmpl) (tmpl: string) -> [map] Extracts all non-overlapping matches of template tmpl.
.matches_template(tmpl) (tmpl: string) -> bool Returns true if the entire string matches template tmpl.
.grid() () -> grid Parses multi-line string into a 2D grid.
.to_int(base?) (base?: int) -> int Parses string into an int with optional radix base.
.to_bigint(base?) / .bigint(base?) (base?: int) -> bigint Parses string into a bigint with optional radix base.
.md5() / .sha256() () -> string Lowercase hex MD5 or SHA-256 digest of the string.
.read_file() / .read_lines() / .read_sections() () -> string | [string] Treats string as a file path and reads its content, lines, or sections.
tinsel
let s = "  x=10, y=-20  ".trim()
assert(s.ints() == [10, -20])
assert("abc".repeat(3) == "abcabcabc")
assert("2025-12-25".replace("-", "/") == "2025/12/25")

3. Array Methods (array)

Method Signature Description
.len() () -> int Number of elements in the array.
.push(item) (item: any) -> array Appends item in-place and returns the array.
.pop() () -> any Removes and returns the last element (or nil if empty).
.clone() () -> array Returns a shallow copy of the array.
.slice(start, end) / .slice_from(start) (start: int, end?: int) -> array Returns sub-array (or use range indexing arr[1..4], arr[..3], arr[2..]).
.map(fn) (fn: (x) -> any) -> array Returns a new array applying fn to each element.
.filter(pred) (pred: (x) -> bool) -> array Returns a new array of elements where pred(x) is truthy.
.fold(init, fn) (init: any, fn: (acc, x) -> any) -> any Left-folds the array from init.
.enumerate() () -> [[int, any]] Returns [index, element] pairs starting at 0.
.sum() () -> int | float Arithmetic sum of elements (0 if empty).
.product() / .prod() () -> int | float Arithmetic product of elements (1 if empty).
.min() / .max() () -> any Minimum or maximum element (nil if empty).
.sort(cmp_or_key?) (fn?: closure) -> array Returns a new sorted array: natural ascending order (0 args), key extractor (1-arg closure), or custom comparator (a, b) -> bool | int (2-arg closure).
.sort_by(key_fn) (key_fn: (x) -> any) -> array Returns a new array stably sorted by key_fn(x).
.sort_desc() () -> array Returns a new array sorted in descending natural order.
.reverse() () -> array Returns a new array with elements in reverse order.
.unique() / .distinct() () -> array Returns a new array with duplicates removed, preserving first-seen order.
.flatten() () -> array Flattens one level of nested arrays.
.transpose() () -> array Transposes a 2D matrix of rows into columns.
.contains(target) (target: any) -> bool Structural membership check (or use target in arr).
.index_of(target) (target: any) -> int 0-based index of first target match via structural equality, or -1.
.join(sep?) (sep?: string) -> string Joins formatted elements with sep (default "").
tinsel
let nums = [4, 1, 4, 3, 2]
assert(nums.unique().sort() == [1, 2, 3, 4])
assert(nums.sort_desc()[..3].product() == 48)
assert([[1, 2], [3, 4]].transpose() == [[1, 3], [2, 4]])

4. Map Methods (map)

Method Signature Description
.len() () -> int Number of key-value entries in the map.
.has(key) / .contains(key) (key: any) -> bool Returns true if key exists in the map (or use key in m).
.get(key, default?) (key: any, default?: any) -> any Returns m[key] if present, or default (nil if omitted).
.set(key, val) (key: any, val: any) -> map Sets m[key] = val in-place and returns the map.
.delete(key) / .remove(key) (key: any) -> map Deletes key from the map in-place and returns the map.
.keys() () -> [any] Returns an array of all keys in the map.
.values() () -> [any] Returns an array of all values in the map.

5. Number Methods (int & bigint)

Method Signature Description
.hex(pad?) / .to_hex(pad?) (pad?: int) -> string Formats int or bigint as lowercase hex, optionally zero-padded to pad digits.
.bin(pad?) / .to_bin(pad?) (pad?: int) -> string Formats int or bigint as binary, optionally zero-padded to pad digits.
.to_bigint() / .bigint() () -> bigint Promotes int to bigint (or returns bigint unchanged).
.to_int() () -> int Downcasts bigint to 64-bit int when in range.

6. Option Methods & Operators (option)

Method / Operator Signature Description
opt? / .is_some() / .is_some () -> bool true for Some(v), false for None.
.is_none() () -> bool true for None, false for Some(v).
opt! / .unwrap() / .value / .val () -> any Returns v from Some(v); panics on None (! / .unwrap()).
.unwrap_or(default) (default: any) -> any Returns v for Some(v) or default for None.
.map(fn) (fn: (v) -> any) -> option Transforms Some(v) into Some(fn(v)), or None into None.
.and_then(fn) (fn: (v) -> option) -> option Flat-maps Some(v) via fn(v), or returns None.
.filter(pred) (pred: (v) -> bool) -> option Keeps Some(v) if pred(v) is truthy, else None.
.or_else(fallback_fn) (fallback_fn: () -> option) -> option Returns self if Some, or calls fallback_fn().
tinsel
let a = Some(10).map(x -> x * 3).filter(x -> x > 20)
let b = None.unwrap_or(99)
assert(a? && a! == 30 && b == 99)

7. Spatial Vector Methods & Properties (vec2 & vec3)

  • vec2 Properties & Operators: .x, .y, +, -, unary -, scalar *, and <-> Manhattan distance (|x_1 - x_2| + |y_1 - y_2|).
    • p.adj4() -> [vec2]: Returns the 4 cardinal neighbors [vec2(x, y-1), vec2(x+1, y), vec2(x, y+1), vec2(x-1, y)].
    • p.adj8() -> [vec2]: Returns all 8 orthogonal and diagonal neighbors around p.
  • vec3 Properties & Operators: .x, .y, .z, +, -, unary -, scalar *, and <-> Manhattan distance (|x_1 - x_2| + |y_1 - y_2| + |z_1 - z_2|).
    • v.adj6() -> [vec3]: Returns the 6 face-adjacent orthogonal 3D neighbors.
    • v.adj26() -> [vec3]: Returns all 26 surrounding 3D neighbors.

8. Range Methods & Properties (range)

  • Properties & Indexing: r.start, r.end, r[offset] ((10..20)[3] == 13).
  • r.len() / r.count() / r.size() -> int: Span length max(0, r.end - r.start).
  • x in r / r.contains(x) / r.has(x) -> bool: O(1) interval membership check.
  • r.intersects(other) / r.overlaps(other) -> bool: Returns true if r and other share at least one integer coordinate.

9. Closure & Module Introspection (closure & module)

  • closure.arity() -> int: Returns the declared parameter count of the function or lambda.
  • module.__name__ / module.name: Module name string.
  • module.__path__ / module.path: Resolved module path string.
  • module.__result__ / module.result: Final expression value produced when the module was evaluated.
  • module.has(name: string) -> bool: Returns true if name is a public export of the module.
  • module.keys() / module.exports() -> [string]: Array of exported symbol names.