Tzopilotl
Docs
GitHub

Standard Library Reference

The standard library is the set of Tzopilotl modules shipped with the interpreter, discovered automatically next to the executable (or via $TZPL_HOME; see the module search path in the language docs). General-purpose modules live under the std.* namespace (import std.strings.*;). Audio-domain modules (synthdef, common_ugens, filters, dsp_math, complex_signal) and host bindings (audio_engine, ui, osc, nats, clock, bundles) keep their flat names.

Functions marked NRT perform blocking syscalls and cannot be called from real-time code; each module's RT-safety is stated in its section. Built-in (C++-implemented) functions are documented separately in the Built-in Functions Reference.

Table of Contents

std.strings

String utilities beyond the built-ins. Pure and RT-safe. String offsets and length are byte-based, matching substring and indexOf.

FunctionDescription
parens(s) / brackets(s) / braces(s) / quotes(s)Wrap in (), [], {}, "".
separatedString([String], sep = " ")Join with a separator.
repeatString(s, n)s repeated n times.
padStart(s, width, pad = " ") / padEnd(s, width, pad = " ")Pad to at least width.
splitLines(s) / lines(s)Split into lines; \r\n normalized, no empty last line from a trailing newline.
capitalize(s)Uppercase the first character (ASCII).
stripPrefix(s, p) / stripSuffix(s, p)Remove a prefix/suffix if present, else unchanged.
equalsIgnoreCase(a, b)ASCII case-insensitive comparison.
glob(s, pattern)Whole-string glob match: *, ?, [abc], [a-z], [!abc].
import std.strings.*;

"7" padStart(3, "0")                -- "007"
"a\r\nb\nc\n" splitLines             -- [a, b, c]
"snare_04.wav" glob("snare_*.wav")  -- true
"beat7" glob("beat[0-9]")           -- true
↑ Back to top

std.path

Pure path-string manipulation — no syscalls, RT-safe. Paths are byte strings with / separators. The filesystem itself lives in std.fs.

FunctionDescription
basename(p)Final component: basename("/a/b/c.txt")"c.txt".
dirname(p)Everything before the last /; "." for bare names.
extension(p)The basename's extension including the dot ("" if none; dotfiles have none).
withExtension(p, ext)Replace (or add) the extension.
joinPath(a, b)Join with exactly one separator; an absolute b wins.
splitPath(p)Components, empty ones dropped: "/a//b"[a, b].
isAbsolute(p)True if the path starts with /.
import std.path.*;

"/a/b/c.txt" basename               -- "c.txt"
"/a/b/c.txt" dirname                -- "/a/b"
"take1.wav" withExtension(".aif")   -- "take1.aif"
joinPath("samples", "kick.wav")     -- "samples/kick.wav"
↑ Back to top

std.fs NRT

Ergonomic wrappers over the NRT file built-ins (readFile, writeFile, listDir, …). Nothing here is real-time safe: the plain wrappers block on syscalls, and the Async wrappers — non-blocking, built on the readFileAsync-family built-ins — are still rejected in real-time code. The Result variants carry a path-bearing error message via std.result.

FunctionDescription
readFileOr(path, default)Contents, or default if unreadable.
readLines(path) → Option[[String]]Contents split into lines.
writeLines(path, [String]) → BoolWrite lines joined with \n, trailing newline.
readFileResult(path) → Result[String, String]readFile with an error message.
readFileBytesResult(path) → Result[Bytes, String]readFileBytes with an error message.
writeFileResult(path, s) → Result[Bool, String]writeFile with an error message.
listDirResult(path) → Result[[String], String]listDir with an error message.
readFileAsyncResult(path) → Future[Result[String, String]]Async readFileResult; await it, then try composes.
readFileBytesAsyncResult(path) → Future[Result[Bytes, String]]Async readFileBytesResult.
writeFileAsyncResult(path, s) → Future[Result[Bool, String]]Async writeFileResult.
import std.fs.*;

readLines("setlist.txt") unwrapOr(["(empty)"]) println;
writeLines("/tmp/out.txt", ["one", "two"]);
readFileResult("missing") errOption unwrap println;
                        -- cannot read file: missing
↑ Back to top

std.result

Result<T, E> is a success-or-error sum type. Convention: built-ins that can fail return Option; stdlib .x APIs that want an error message return Result<T, String>.

FunctionDescription
Result<T, E>.ok(v) / Result<T, E>.err(e)Constructors.
isOk(r) / isErr(r)Case tests.
okOption(r) / errOption(r)Either side as an Option.
unwrapResult(r)The ok value; traps on err.
unwrapOr(r, default)The ok value or a default.
unwrapOrElse(r, f)The ok value or f(err).
mapOk(r, f) / mapErr(r, f)Transform one side, pass the other through.
import std.result.*;

fn half(x Int) Result<Int, String> {
    x % 2 == 0 ? Result<Int, String>.ok(x / 2)
               : Result<Int, String>.err("odd: " $ x toString)
}

half(8) unwrapOr(0) println;                 -- 4
half(7) errOption unwrap println;            -- odd: 7

The postfix try operator propagates errors without boilerplate: expr try unwraps ok/some, and on err/none early-returns it from the enclosing function (whose return type must be a Result with the same error type, or an Option). It chains mid-pipeline like await.

fn quarter(x Int) Result<Int, String> {
    let h = half(x) try;         -- err propagates out of quarter
    let q = half(h) try;
    Result<Int, String>.ok(q)
}

quarter(8) unwrapOr(0) println;              -- 2
quarter(6) errOption unwrap println;         -- odd: 3
↑ Back to top

std.test

Assertion helpers with stable one-line output (PASS label / FAIL label: expected X got Y), designed to compose with the golden-file test runner and read well in the app's output panel. Each assertion returns its outcome as a Bool and updates shared counters.

FunctionDescription
assertEq<T>(actual, expected, label)Structural equality.
assertTrue(cond, label) / assertFalse(cond, label)Boolean conditions.
assertNear(actual, expected, eps, label)Float comparison within a tolerance.
check(label, f () Bool)Run a named check function.
testSummary() → IntPrint N passed, M failed; return the failure count.
import std.test.*;

assertEq(2 + 2, 4, "ints add");       -- PASS ints add
assertNear(0.1 + 0.2, 0.3, 1e-9, "float near");
let failures = testSummary();          -- 2 passed, 0 failed
↑ Back to top

std.thunk

Memoized lazy values: a Thunk<T> wraps a deferred computation that runs at most once; force evaluates it on first use and caches the result in place.

FunctionDescription
thunk<T>(f () T) → Thunk<T>Wrap a deferred computation.
force<T>(t Thunk<T>) → TEvaluate on first force, then return the cached value.
import std.thunk.*;

let t = thunk(fn() Int { expensive() });
t force println;    -- computed now
t force println;    -- cached
↑ Back to top

std.futures

Combinators over Future<T> from the async/await core.

FunctionDescription
awaitAll<T>(fs [Future<T>]) → VoidBarrier: wait for every future to resolve.
gather<T>(fs [Future<T>]) → [T]Await all and collect results in input order.
↑ Back to top

std.json

The Json value enum (null, bool, number, string, array, object) and toString rendering. A parser returning Result<Json, String> is planned (see the roadmap in devplans/LANG_IMPLEMENTATION_PLAN.md). For fast binary interchange, prefer std.message's TZB codec.

↑ Back to top

std.message / std.messageEncoding

Msg is the dynamic message value type (bool/int/float/symbol/string/vec) with asMsg constructors; std.messageEncoding provides the TZB binary codec: encode(Msg) → Bytes, decode(Bytes) → Msg, isMessage, and a zero-copy Reader with O(1) child access for columnar vectors. Used by the actor system and the NATS bridge. The TZB format itself — the wire layout and the matching C++ API — is documented in FFI Guide §15, Binary Messages.

↑ Back to top

std.notebook NRT

Builds the app's .tzd notebook documents (Live Controls & Notebooks) programmatically — a .tzd file is a TZB-encoded Msg tree, so this module assembles the document records and hands them to std.messageEncoding. Cells are described with NotebookCell values, normally via the constructors below. Generated documents contain no widget records — give the notebook a run-on-load code cell and its ui constructors recreate the widgets on open — and no undo history, so the file opens with a fresh history tree.

FunctionDescription
proseCell(text)A prose (text) cell.
codeCell(text, runOnLoad = false, name = "")A code cell; name is the optional header label.
panelCell(name, height = 240.0)A panel cell claiming widget panel name.
presetsCell(name = "")An empty presets cell; slots are captured in the GUI.
saveNotebook(path, [NotebookCell]) → BoolEncode and write the document to path.
notebookBytes([NotebookCell]) → BytesThe encoded document, without writing a file.
notebookMsg([NotebookCell]) → MsgThe document as a Msg tree, for inspection.
import std.notebook.*;

saveNotebook("demo.tzd", [
    proseCell("# Sine demo"),
    panelCell("main"),
    codeCell("import ui.*;\npanel(\"main\");\nslider(\"freq\", 20.0, 2000.0, 440.0);", true),
]);
↑ Back to top