Standard Library (std/*) Reference
The Tinsel Standard Library is implemented in pure Tinsel source files (stdlib/*.tin) embedded directly into the standalone Go binary via embed.FS. Every module can be imported using either its canonical "std/<name>" path or shorthand "<name>":
import "std/math" as math
from "std/search" import dijkstra, bfs, union_find
from "std/grid" import parse_grid, forward, turn_right
Module Directory
| Module | Source File | Primary Exports & Types |
|---|---|---|
std/grid |
stdlib/grid.tin |
grid type, parse_grid, new, cardinal_dirs, forward, turn_right, turn_left, flood_fill |
std/intervals |
stdlib/intervals.tin |
rangeset type, range_set, overlap, split, remap |
std/search |
stdlib/search.tin |
dijkstra, astar, bfs, dfs, toposort, union_find / dsu |
std/orbit |
stdlib/orbit.tin |
orbit / cycle for O(1) modulo cycle fast-forwarding |
std/math |
stdlib/math.tin |
gcd, lcm, crt, ext_gcd, mod_inv, mod_pow, shoelace, picks_theorem, cramer_2x2 |
std/iter |
stdlib/iter.tin |
Lazy Iter streams, iter, count_from, repeat_val, combinators & consumers |
std/itertools |
stdlib/itertools.tin |
windows, chunked, zip, frequencies, permutations, combinations, product |
std/collections |
stdlib/collections.tin |
defaultdict (DefaultDict), counter (Counter) |
std/set |
stdlib/set.tin |
set hash set with .add(), .has(), .union(), .intersect(), .diff(), .is_subset() |
std/deque |
stdlib/deque.tin |
deque amortized O(1) double-ended queue |
std/heap |
stdlib/heap.tin |
heap / priority_queue binary min-heap with .push(), .pop(), .peek(), .len(), and optional comparator |
std/memo |
stdlib/memo.tin |
memoize(fn) automatic recursive function caching |
std/vec |
stdlib/vec.tin |
N-dimensional coordinate vectors, adj_ortho, adj_all, manhattan, euclid_sq |
std/io & std/parse |
stdlib/io.tin, stdlib/parse.tin |
File readers, parse_ints, parse_grid, scan_pattern, parse_template |
| Prototype & Prelude Modules | stdlib/array.tin, string.tin, int.tin, option.tin, prelude.tin |
Backing implementations for built-in receiver methods and global prelude functions |
1. std/grid
2D character grid engine, directional heading arithmetic, and coordinate geometry (stdlib/grid.tin).
Constructors & Module Functions
parse_grid(text: string) -> grid/parse(text: string) -> grid: Parses a multi-line string into a row-major 2D charactergrid(also available as"text".grid()).new(w: int, h: int, fill_char = '.') -> grid: Allocates aw\timeshgrid initialized withfill_char.make_grid(w: int, h: int, data: array) -> grid: Wraps a flat row-major array of lengthw * hinto agrid.cardinal_dirs/dirs: The 4 cardinal direction vectors in clockwise order:[vec2(1, 0), vec2(0, 1), vec2(-1, 0), vec2(0, -1)](0: East,1: South,2: West,3: North).turn_right(dir: int) -> int:(dir + 1) % 4(clockwise 90°).turn_left(dir: int) -> int:(dir + 3) % 4(counter-clockwise 90°).opposite(dir: int) -> int:(dir + 2) % 4(180° reversal).forward(pos: vec2, dir: int) -> vec2:pos + cardinal_dirs[dir].manhattan(p1, p2) -> int: Manhattan distancep1 <-> p2.
grid Properties, Operators & Instance Methods
On a grid instance g, .width (.w) and .height (.h) are integer fields, not methods (g.width, g.height).
- Fields:
g.width/g.w(columns),g.height/g.h(rows). - Operators:
g[pos]: Reads character atvec2coordinatepos(nilif out of bounds).g[pos] = ch: Mutates cell atposin-place.pos in g/pos !in g: Checks if0 <= pos.x < g.width && 0 <= pos.y < g.height.
- Methods:
g.get(pos) -> char | nil,g.set(pos, ch) -> grid,g.in_bounds(pos) -> bool.g.find(ch) -> vec2 | nil: First coordinate matchingchin row-major order.g.find_all(ch) -> [vec2]: All coordinates matchingch.g.count(ch) -> int: Total occurrences ofch.g.adj4(pos) -> [vec2]/g.neighbors4(pos): Cardinal neighbors strictly inside grid bounds.g.adj8(pos) -> [vec2]/g.neighbors8(pos): 8-way neighbors strictly inside grid bounds.g.cells() -> [[vec2, char]]: Array of[pos, ch]pairs in row-major order.g.rows() -> [string],g.cols() -> [string]: Rows or columns as strings.g.rotate_cw() -> grid,g.rotate_ccw() -> grid,g.flip_h() -> grid,g.flip_v() -> grid,g.transpose() -> grid,g.clone() -> grid.g.flood_fill(start: vec2, can_visit?: (pos, ch) -> bool) -> [vec2]: 4-way connected component starting atstart(defaults to matchingg[start]).
import "std/grid" as grid
let g = grid.parse_grid("S..\n.#.\n..E")
assert(g.width == 3 && g.height == 3)
assert(g.find('E') == vec2(2, 2))
assert(g.adj4(vec2(0, 0)) == [vec2(1, 0), vec2(0, 1)])
2. std/intervals
Interval algebra and normalized disjoint RangeSet transformations (stdlib/intervals.tin).
Module Functions
range_set(ranges?: [range]) -> rangeset: Constructs a normalizedrangesetby sorting and merging overlapping or adjacent half-open intervals.overlap(r1: range, r2: range) -> range | nil: Intersection ofr1andr2, ornilif disjoint.split(src: range, cutter: range) -> [range | nil]: Trisectssrcagainstcutterinto[prefix, overlap, suffix].remap(rs: rangeset, rules: [[dest, src, len]]) -> rangeset: Applies piecewise interval translation rules tors.
rangeset Instance Methods & Operators
x in rs/rs.contains(x) -> bool: Checks if integerxfalls inside any interval ofrs.rs.len()/rs.count()/rs.size() -> int: Total integer points covered across all disjoint intervals.rs.min() -> int | nil/rs.max() -> int | nil: Smallest or largest integer coordinate covered byrs.rs.ranges() -> [range]: Underlying sorted array of disjointrangevalues.rs.add(r: range) -> rangeset: Insertsrand re-normalizes.rs.union(other: rangeset) -> rangeset,rs.intersect(other: rangeset) -> rangeset,rs.diff(other: rangeset) -> rangeset.rs.remap(rules: [[dest, src, len]]) -> rangeset: Trisects and shifts intervals matching any[dest, src, len]rule while passing unmatched sub-intervals through unchanged.
from "std/intervals" import range_set
let rs = range_set([10..20, 15..30]).remap([[100, 18, 5]])
assert(rs.len() == 20 && rs.min() == 10 && (102 in rs))
3. std/search
Declarative state-space pathfinding, topological sorting, and Disjoint-Set Union (stdlib/search.tin).
Graph Search Functions (dijkstra, astar, bfs, dfs, search)
All four search routines accept an options map and return SearchResult(found: bool, cost: int, path: [state]):
dijkstra({ start, step, goal?, cost? }) -> SearchResult: Weighted shortest path using a binary min-heap.step(state)may return[next_state, edge_cost]pairs or plainnext_statevalues (with cost1orcost(curr, next)).astar({ start, step, goal, h, cost? }) -> SearchResult: Heuristic A^* search minimizing g(s) + h(s).bfs({ start, step, goal? }) -> SearchResult: Unweighted breadth-first search using an O(1) queue.dfs({ start, step, goal? }) -> SearchResult: Depth-first search traversal.search(kind: string, opts: map) -> SearchResult: Dispatches"dijkstra","astar","bfs", or"dfs".
toposort(graph_or_edges, less?) -> [any] | nil
Kahn's topological sort over an edge list [[u, v], ...] or adjacency map { u: [v1, v2] }. Returns nil if a cycle exists. Pass an optional comparator less: (a, b) -> bool for priority-queue tie-breaking.
union_find(initial_items?) -> UnionFind / dsu(initial_items?)
Disjoint-Set Union with path compression and union-by-size:
.add(x) -> any,.find(x) -> any,.union(x, y) -> bool,.connected(x, y) -> bool,.size(x) -> int,.count() -> int,.groups() -> map.
from "std/search" import bfs, toposort, union_find
let res = bfs({ start: 1, goal: 16, step: x -> [x * 2, x + 1] })
assert(res.found && res.cost == 4)
assert(toposort([["A", "B"], ["B", "C"]]) == ["A", "B", "C"])
4. std/orbit
Periodicity detection and O(1) modulo fast-forwarding (stdlib/orbit.tin).
orbit({ initial, steps, step, hash? }) -> any / cycle(...)
Advances state = step(state) while recording each seen state (or hash(state)) and its step index. As soon as a state repeats at step t matching earlier step t_0 (period P = t - t_0), orbit fast-forwards the remaining steps via (N - t) \bmod P and returns the exact state at step steps.
from "std/orbit" import orbit
let ans = orbit({ initial: 2, steps: 1_000_000_000_000, step: x -> (x * 5 + 1) % 29 })
assert(type_of(ans) == "int")
5. std/math
Number theory, modular arithmetic, linear algebra, and computational geometry (stdlib/math.tin).
| Function / Constant | Signature | Description |
|---|---|---|
PI, E |
float |
\pi \approx 3.141592653589793, e \approx 2.718281828459045 |
gcd(a, b) / lcm(a, b) |
(int, int) -> int |
Greatest common divisor and least common multiple |
ext_gcd(a, b) |
(int, int) -> [gcd, x, y] |
Extended Euclidean algorithm (a x + b y = \gcd(a, b)) |
euclid_mod(a, m) |
(int, int) -> int |
Non-negative modulo ((a % m) + m) % m |
mod_pow(base, exp, m) |
(int, int, int) -> int |
Modular exponentiation base^{exp} \pmod m |
mod_inv(a, m) |
(int, int) -> int | nil |
Modular multiplicative inverse a^{-1} \pmod m (nil if not coprime) |
crt(rems, mods) |
([int], [int]) -> int | nil |
Chinese Remainder Theorem solver for x \equiv r_i \pmod{m_i} |
pow(base, exp) |
(num, num) -> int | float |
Binary integer exponentiation (or float power when float/negative exp) |
sign(n) / clamp(x, lo, hi) |
(num) -> int, (num, num, num) -> num |
Signum (-1, 0, 1) and interval clamping |
shoelace(pts) |
([vec2 | [int]]) -> int |
Twice the polygon area (2A) via the Shoelace formula |
picks_theorem(double_area, perim) |
(int, int) -> PickResult |
Returns PickResult(interior, total, boundary) lattice points via Pick's Theorem |
cramer_2x2(eq1, eq2) |
([a1, b1, c1], [a2, b2, c2]) -> [x, y] | nil |
Exact integer solver for 2 \times 2 linear systems via Cramer's Rule |
6. std/iter
Lazy pull-based stream iterators (stdlib/iter.tin).
- Constructors:
iter(x)/x.iter(),count_from(start, step = 1),repeat_val(val),Iter(next_fn). - Lazy Combinators (
-> Iter):.map(f),.filter(pred),.take(n),.skip(n)/.drop(n),.take_while(pred),.drop_while(pred),.enumerate(),.zip(other),.chain(other). - Terminal Consumers:
.collect()/.to_array(),.fold(init, f),.sum(),.product(),.count()/.len(),.min(),.max(),.find(pred),.any(pred),.all(pred).
7. std/itertools
Combinatorics and sequence windowing (stdlib/itertools.tin).
windows(arr, size) -> [array]: Overlapping sliding windows of lengthsize.chunked(arr, size) -> [array]: Non-overlapping chunks of up tosizeelements.zip(arr1, arr2) -> [[a, b]]: Pairs elements from two arrays.frequencies(arr) -> map/counter(arr) -> map: Returns{ item: count }frequency map.unique(arr) -> array/distinct(arr) -> array: Deduplicates while preserving order.product(arr1, arr2) -> [[a, b]]: Cartesian product of two arrays.permutations(arr, r = arr.len()) -> [array]: All length-rpermutations.combinations(arr, r) -> [array]: All length-rcombinations without replacement.
8. std/collections
Struct-backed auto-vivifying maps and frequency counters (stdlib/collections.tin).
defaultdict(factory) -> DefaultDict: Auto-initializes missing keys usingfactory(a default value like0or[], or a zero-arg closure). Supportsd[k],d[k] = v,k in d,len(d),.get(k),.set(k, v),.inc(k, delta = 1),.push(k, item),.keys(),.values(),.entries(),.map().counter(items?) -> Counter: Counts element frequencies in an array or string. Supportsc[k],k in c,len(c),.get(k),.inc(k, delta = 1),.most_common(n?),.total(),.keys(),.values(),.entries().
9. std/set
Hash set algebra (stdlib/set.tin).
set(items?: array) -> set: Creates a hash set supportingx in s,x !in s,s.len(),s.has(x),s.add(x),s.delete(x),s.to_array(),s.union(s2),s.intersect(s2),s.diff(s2), ands.is_subset(s2).
10. std/deque
Amortized O(1) double-ended queue implemented with dual opposing stacks (stdlib/deque.tin).
deque(items?: array) -> deque: Supports.push_back(x)/.push(x),.push_front(x),.pop_front()/.pop(),.pop_back(),.peek_front(),.peek_back(),.len(),.is_empty(),.to_array().
11. std/heap
Binary min-heap priority queue supporting both struct instances and mutable arrays (stdlib/heap.tin).
heap(items?: array, less?: (a, b) -> bool) -> heap/priority_queue(...): Constructs a min-heap struct supporting.push(item),.pop(),.peek(),.len(),.is_empty(), and.to_array().push(heap, item: any, less?: (a, b) -> bool): Insertsitemin O(\log n).pop(heap, less?: (a, b) -> bool) -> any: Removes and returns minimum element in O(\log n).peek(heap) -> any: Returns minimum element in O(1) (nilif empty).len(heap) -> int/is_empty(heap) -> bool: Number of elements inheap.
12. std/memo
memoize(fn: closure) -> closure(stdlib/memo.tin): Wraps a 1-argument or multi-argument function closure with a structural hash cache table.
13. std/vec
Generic N-dimensional coordinate vector operations (stdlib/vec.tin) operating on [int] coordinate arrays of any dimension N:
add(v1, v2),sub(v1, v2),scale(v, k),dot(v1, v2),manhattan(v1, v2),euclid_sq(v1, v2),zero(dim),unit(dim, axis).adj_ortho(v: [int]) -> [[int]]: Generates the 2N orthogonal neighbors.adj_all(v: [int]) -> [[int]]: Generates all 3^N - 1 surrounding neighbors (8 in 2D, 26 in 3D, 80 in 4D).
14. std/io and std/parse
std/io(stdlib/io.tin): Exportsread_file,read_lines,read_sections,read_paragraphs,write_file,append_file,file_exists,env,print,println.std/parse(stdlib/parse.tin): Exportsints/parse_ints,grid/parse_grid,parse_sections/parse_paragraphs,scan_pattern/scan,parse_template,matches_template.
15. Prototype and Prelude Modules
The remaining five files in stdlib/ power Tinsel's global prelude and built-in receiver methods (see Built-in Functions & Receiver Methods Reference for full signatures):
std/prelude(stdlib/prelude.tin): Global functionslen,lines,sum,iter,min,max,abs,map,assert,read_lines,read_sections,to_hex/hex,to_bin/bin,scan_pattern/scan.std/array(stdlib/array.tin): Prototype methods onarray(can also be imported for|>pipelines:from "std/array" import filter, sort_by).std/string(stdlib/string.tin): Prototype methods onstring.std/int(stdlib/int.tin): Prototype methods onintandbigint.std/option(stdlib/option.tin): Prototype methods and combinators onoption(Some/None).