Overview and philosophy
dusk is a small systems language that compiles to native code through textual LLVM IR. Every file picks a paradigm with @paradigm procedural, functional, or oop, and that choice unlocks the matching builtins. Values are immutable by default, memory is explicit, and errors are values you handle.
This page lays out the philosophy that the rest of the reference builds on. The reference describes the 0.1.0 core with the changes the 0.2.x and 0.3.x releases layered on top; each page notes where the current language differs from the baseline.
Core philosophy
Section titled “Core philosophy”The specification opens with six commitments, and the checker holds the line they draw.
- Immutability by default. All values are immutable unless explicitly declared mutable with
mut. Immutability covers element and field stores, not just rebinding. - Explicit over implicit. Allocations, dereferences, paradigm usage, and error handling are never hidden.
- Multiple paradigms with enforced discipline. Paradigms are opt in per file through directives. Using a paradigm feature the file has not declared is a compile error in that file. See Paradigm system.
- Systems level control. Manual memory management by default. No garbage collector unless explicitly opted into through the standard library.
- All declared variables must be used. An unused variable is a compile error. This is never suppressible.
- All errors must be handled. Ignoring an error return is a compile error. See Error handling.
A small complete program shows several of these at once: the file declares the functional paradigm before it may call map and foreach, every binding is immutable, and every binding is used.
@paradigm functional
func main() -> int32 { nums: int64[] = [1, 2, 3, 4, 5] doubled := map(nums, lambda (n: int64) -> int64 { return n * 2 }) foreach(doubled, lambda (n: int64) -> void { println(n) }) return 0}What the checker holds
Section titled “What the checker holds”The static checker holds the line the spec draws:
- Integer and float widths never mix silently.
- Immutability extends to element and field stores.
- Every array index and range slice is bounds checked, and a bound error must be handled.
- An allocation is sized by its declared type.
- Printing dispatches through
Displayor fails to compile. - A private name never leaves its file.
Beyond the static checks, the default heap since 0.2.x is generational: every managed pointer carries a generation that is checked at each dereference, so a use after free, a double free, or a stale pointer to a reused block faults instead of corrupting memory. See Memory management for the managed and raw pointer split.
Compilation model
Section titled “Compilation model”The compiler is written in Rust with zero dependencies. It runs the whole pipeline itself: it lexes, parses, resolves names, type checks, monomorphizes, and emits textual LLVM IR. The IR is handed to clang for native code generation, and each program links against a small C runtime.
Two consequences follow from this design:
- Building dusk programs requires
clangand LLVM on your path. The textual IR targets one LLVM major version; as of 0.3.3 that is LLVM 22.x. - The compiler binary itself needs nothing beyond the Rust standard library to build.
The compiler finds its standard library and C runtime beside itself. The DUSK_HOME environment variable overrides the search when you want a binary to use a different toolchain tree, such as a source checkout. The standard library under lib/std is written in dusk itself; see the standard library overview.
The dusk binary exposes each pipeline stage as a command (lex, scan, parse, check, build, run, demo, version); see the CLI reference. Dawn is the accompanying package tool, which treats a package as a git repository; see Dawn and Packages.
Status and versioning
Section titled “Status and versioning”The current release is 0.3.3. The language is pre 1.0, and every minor release changes it, so installing today means tracking a moving target. The CHANGELOG records the release by release history; in outline:
- 0.1.0 is the core language the specification describes.
- 0.2.0 through 0.2.6 add memory safety: the
StringBuilder, the split between managed*Tand raw*raw Tpointers, the generational heap, single ownership withrefandmove, escape checking for the clear cases, andforeign "C"calls into libc across the raw pointer boundary. - 0.3.0 through 0.3.3 add concurrency:
spawnandjoinfor OS threads, thread safe generational checking, atomics, channels with blocking and non-blocking operations, mutexes and condition variables that fault by name on classic pthread misuse, and a global thread pool with thesubmitbuiltin. See Threads and the memory model.
The 0.4.x releases build the async layer on this substrate; see the roadmap.
Where this reference describes 0.1.0 behavior that a later release changed (immutable-only strings, a single pointer kind, debug-only memory safety), the affected page carries a version caveat.
Where to go next
Section titled “Where to go next”- New to the language: start with Getting started and the language tour.
- The reference proper begins with source files, directives, imports, and exports.
- Runnable programs live in the repository’s
examples/directory and in the examples guide. - The source is at github.com/choice404/dusk, dual licensed under MIT or Apache 2.0.