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.
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.
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")
}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
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.
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.
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.
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.
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.
The Limen compiler is also written in Limen, and builds itself to the same C as the original compiler.
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.