Limen
Limen

Code can only do what it was handed.

Limen is a small compiled language with no ambient authority. Files, the network, the clock and other programs are reached only through capabilities, values a function is given as arguments. A function's signature tells you everything it can do.

Read the book Install

fn main(root: Root) -> Result[(), IoError] {
    let notes = root.fs.under("notes").read_only()
    let text = load(notes)?
    report(root.stdout, count_words(text))
    Ok(())
}

// Can read files under notes/, and nothing else.
fn load(fs: Fs) -> Result[Str, IoError] {
    fs.read("today.txt")
}

// Can only compute: no file, network, clock or output.
fn count_words(text: Str) -> Int {
    text.split(" ").filter(|w| w != "").len()
}

// Can print, and nothing else.
fn report(out: Stdout, n: Int) {
    out.print("{n} words")
}
examples/home-01-caps/main.lmn

Authority is in the signature

main receives root, the only source of authority, and hands each function exactly the part it needs: load may read files under notes/, report may print, count_words may do neither.

The compiler knows this too. limen caps lists what every function can reach:

$ limen caps main.lmn
main         Root
load         Fs
count_words  pure
report       Stdout

Dependencies you can trust

Each dependency in limen.toml lists the capabilities it may receive, and the compiler checks every function it exports against that list. A library that parses dates cannot open a socket.

Narrow, then hand out

fs.under("data").read_only(), net.only("api.example.com"), a program with only some arguments: authority is narrowed before it is passed on, and can be revoked.

Compiled to native code

Limen compiles through C to a single binary, with reference counting and no garbage collector pauses. The same programs also run in an interpreter for quick edits.

Concurrency with a shape

Tasks live inside a group and never outlive it. Deadlines cancel what is still running, panics come back to the caller, and channels, atomics and shared values are safe by construction.

Two layers of protection

Every program also runs in an operating-system sandbox built from the same grants, so C code and the runtime itself stay inside what the program was given.

Written in itself

The Limen compiler is also written in Limen, and builds itself to the same C as the original compiler.

Install

On macOS with Apple silicon:

$ brew install alfonsocampodonico/limen/limen
$ limen run hello.lmn

Programs compile through C, so the Xcode Command Line Tools need to be installed. Then start with chapter 1 of the book.