dusk

a small systems language · v0.3.3

Readable all the way down.

dusk compiles to textual LLVM IR you can open in an editor. Immutable by default, memory that faults loudly instead of corrupting silently, errors you can't ignore, and one paradigm per file.

Get started Open the playground cargo install dusk-lang
main.dusk
@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
}
main.ll, what the compiler emits
define i64 @lambda.0(ptr %env, i64 %a0) {
entry:
  %t0 = alloca i64
  store i64 %a0, ptr %t0
  %t1 = load i64, ptr %t0
  %t2 = mul i64 %t1, 2
  ret i64 %t2
}

define void @lambda.1(ptr %env, i64 %a0) {
entry:
  %t0 = alloca i64
  store i64 %a0, ptr %t0
  %t1 = load i64, ptr %t0
  call void @cool_println_i64(i64 %t1)
  ret void
}

This pair is real: the exact IR dusk 0.3.3 emits for the program on the left, trimmed to the two lambdas. n * 2 is the mul; clang links the rest against a small C runtime. See your own program's IR →

0-6° · civil twilight

One paradigm per file

Every file declares @paradigm procedural, functional, or oop, and only the matching builtins exist there. A file reads the way it says it will.

6-12° · nautical twilight

Errors are values

A fallible function returns (value, error), and an unhandled error stops the compile. No runtime surprise three weeks later.

12-18° · astronomical twilight

Memory that faults, not corrupts

Every managed pointer carries a generation checked at each dereference. Use-after-free, double free, and stale pointers fault by name.

Three phases of dusk, from source down to the metal.

Monomorphized generics

Generic functions and types specialize at compile time. No runtime type resolution, ever.

Interfaces, no inheritance

Vtable dispatch through interfaces; printing goes through Display or fails to compile.

Functional when you want it

map, filter, reduce, fold, and foreach, plus monads with do notation. The functional paradigm unlocks all of it.

Concurrency that faults by name

Threads, bounded channels, mutexes, and a thread pool. Every classic pthread misuse faults with its name, not undefined behavior.

Packages are git repositories

dawn fetches Go-style imports like "github.com/user/repo/module" into a local cache. No registry to gatekeep.

A toolchain you can hold

A zero-dependency compiler in Rust, a small C runtime, and eight CLI commands that mirror the pipeline.

Get dusk

# from crates.io
cargo install dusk-lang

# on Arch Linux, from the AUR
paru -S dusk-lang-git

You'll need clang and LLVM 22.x on your path, since dusk emits one LLVM major version's textual IR. The language is pre-1.0 and every minor release changes it, so the roadmap says where it's headed. Then take the first steps or skim the language tour.