rok
rok logo

rok

A small language with a rich library.
Static types, closed sum types, AOT compilation, plus a REPL and Jupyter.
curl -fsSL https://rok-lang.org/install.sh | sh

macOS and Linux. Windows and archives: Download.

A | B

Closed sum types

An enum or T | none names every case, and match checks that you handled them all.

??

No null surprises

A missing value is none in the type; ?? gives the default.

throws

Errors you can see

throws (E) is part of the signature; the caller writes try or catch.

AOT

Native programs

Compiled ahead of time, with LLVM built into rokc: nothing else to install.

>_

REPL and Jupyter

Try an idea at the prompt or in a notebook, then keep it as a script.

◎

Stones

Packages from rokstones.io, added with rok add and pinned in rok.lock.

What is rok

rok is a programming language that aims to be "one language for everything you want to do". Its design follows two slogans.

  • A small language, a rich library. Most of what defines how a language feels (numeric semantics, conversions, collections, IO, concurrency) lives in the standard library.
  • Freedom within control. Static types, closed sum types, no traits-as-types, no implicit promotion, and AOT-only compilation narrow the paths you can take; in exchange, the code within them is predictable.

The full motivation and philosophy are in the spec introduction.

At a glance

Sum types and match, T | none and ??, and error flow made explicit with throws / try / catch.

enum Shape {
    Circle(f64),
    Rect { w: f64; h: f64; },
}

fn area(s: Shape) -> f64 {
    match s {
        Shape::Circle(r) => 3.14159 * r * r,
        Shape::Rect { w, h } => w * h,
    }
}

fn find(xs: List<str>, key: str) -> usize | none {
    for i in 0..xs.len() {
        if xs[i] == key { return i; }
    }
    none
}

fn parse_port(s: str) throws (ParseError) -> u16 {
    try s.parse::<u16>()
}

fn main() {
    let shapes = [Shape::Circle(1.0), Shape::Rect { w: 2.0, h: 3.0 }];
    for s in shapes { println(f"area = {area(s):.2}"); }

    let at = find(["ada", "grace", "linus"], "grace") ?? 99;
    println(f"grace at {at}");

    let port = try parse_port("80x") catch e { 8080u16 };
    println(f"port {port}");
}
area = 3.14
area = 6.00
grace at 1
port 8080

A one-line script runs as is.

println("Hello, world!");
Hello, world!

Packages

rok packages are called stones. Add a stone from the rokstones.io registry as a dependency with rok add <name>, or a local path or git repository with rok add <name> --path <dir> / --git <url>. See Modules and Packages for details.