Grasm v1.0.0 Get started

Start

Getting started

A first program, run three ways, in about two minutes.

1. Write it

Put this in hello.gr.

fn main() {
    print("hello from grasm")
}

main needs no effect row: it is the entry point, and the capability to print is granted there. Every other function that prints must say so.

2. Run it

grasm run hello.gr

That is the interpreter, and it is normative: where the engines could ever disagree, it is the one that is right by definition.

3. Compile it

grasm build hello.gr --native -o hello
./hello

Ahead-of-time through Cranelift. Byte-for-byte the same stdout, the same exit code. Drop --native and you get a bundle instead — the interpreter with your program attached, one file, no toolchain needed to run it.

4. Something that can fail

Failure is a value, not an exception. A function that can fail says so in its type, and a caller that ignores it does not compile.

type MathError = | DivByZero

fn safe_div(a: i64, b: i64) -> i64 ! MathError {
    if b == 0 {
        fail(DivByZero)
    }
    a / b
}

fn main() {
    match safe_div(10, 0) {
        Ok(v) -> print("{v}")
        Err(e) -> print("caught: {e}")
    }

    // or take a default and move on
    print("{safe_div(10, 0) ?? 0 - 1}")
}

test "division works" {
    let v = try safe_div(10, 2)
    assert_eq(v, 5)
}

Tests live beside the code and run with grasm test.

Next

A tour of the language

Types, pattern matching, closures, generics — the whole surface in one read.

Effects and capabilities

The part that is unlike other languages, and the reason to use this one.