Standard library overview
The dusk standard library lives under lib/std in the repository and is written in dusk itself. It is small and deliberate: console and file I/O, string helpers, two collections, allocators, two functional enums, and the concurrency modules.
Importing a module
Section titled “Importing a module”Import a module with a dotted path in an @import directive at the top of the file, before declarations.
@import std.io@import std.functional.maybeA dotted path resolves to a module (a directory or a file) or to a leaf symbol inside a file.
@import std.io // module@import std.io.print_line // one symbolAfter a module import the module’s exported names are in scope flat, so @import std.io lets you call print_int and print_line with no prefix. A qualified call through the module path reaches the same function, so std.io.print_line("hi") also works. Enum constructors keep their type name: after @import std.functional.maybe you write Maybe.Some(42) and Maybe.None.
Imports are independent of paradigm directives. Importing a module does not grant any paradigm; a file that wants while and mut still declares @paradigm procedural itself. See Source files for the full import and export rules.
Some names need no import at all. print, println, printerr, alloc, free, read_file, write_file, read_line, read_all, spawn, join, and submit are builtins, available everywhere. See Builtins.
What ships
Section titled “What ships”Every module below is in the tree today, written in dusk under lib/std.
| Module | What it holds | Details |
|---|---|---|
std.io | print_int, print_line, typed line input with read_int and read_float | I/O |
std.string | str_len, str_eq, the parsers, and the growable StringBuilder | Strings |
std.vector | Vector<T>, a growable heap array | Collections |
std.map | Map<V>, a hash map from string keys, returning Maybe<V> on lookup | Collections |
std.memory.allocator | The Allocator interface with the Heap, FixedBuffer, and Debug allocators | Memory |
std.memory.arena | Arena, a bump allocator reset or destroyed as a whole | Memory |
std.functional.maybe | Maybe<T> with is_some and unwrap_or | Functional |
std.functional.either | Either<L, R> with is_left and left_or | Functional |
std.concurrent.thread | sleep_ms, beside the spawn and join builtins | Concurrency |
std.concurrent.atomic | AtomicInt, sequentially consistent int64 atomics | Concurrency |
std.concurrent.channel | Channel<T>, a bounded, thread-safe queue, with try and timeout variants | Concurrency |
std.concurrent.sync | Mutex and Condvar | Concurrency |
std.concurrent.pool | pool_start, pool_shutdown, and ncpu for the global thread pool behind submit | Concurrency |
A short program that touches both collections:
@paradigm procedural
@import std.vector@import std.map@import std.functional.maybe
func main() -> int32 { v: *Vector<int64> = alloc(vec_new()) mut i: int64 = 0 while i < 3 { vec_push(v, i * 10) i = i + 1 } println("vector holds {} elements", vec_len(v)) println("v[2] = {}", vec_get(v, 2))
m: *Map<int64> = alloc(map_new()) map_put(m, "answer", 42) println("answer = {}", unwrap_or(map_get(m, "answer"), 0))
vec_free(v) free(v) map_free(m) free(m) return 0}Both collections follow the same shape: build the value on the heap with alloc, pass it by pointer so growth persists across calls, free the backing buffer with the module’s _free function, then free the struct itself with free. StringBuilder and Arena follow the same pattern. The memory guide covers the ownership rules behind it.
Planned next
Section titled “Planned next”These modules aren’t in the tree yet. They sketch where the library is headed, not a schedule.
std.functional.result:Result<T, E>, a success value or a typed error, for code that wants a typed failure channel instead of the(T, error)tuple.std.functional.io:IO<T>, a monad wrapping side effecting work so it composes with do notation.std.logging: structured logging with levels and output redirection, built onstd.io.std.memory.collector: a garbage collector exposed as an allocator, first as a conservative collector.- Unicode aware string operations, extending the byte oriented helpers in
std.string. List<T>and a wider set of helpers acrossMaybe,Either, andResult, so do notation reaches more shapes.
Two entries from the original plan have since shipped: std.map, and mutable strings as StringBuilder in std.string.