Systems Programming
in Harmony

Lira combines Go-like fiber concurrency with pattern matching and strong typing. Write concurrent code that's as elegant as it is fast.

hello.li
fn main() {
    let fibers = [1, 2, 3].map(fn(n) {
        spawn {
            sleep(100)
            return n * n
        }
    })

    let results = fibers.map(fn(f) { await(f) })
    println("Squares: {results}")
}

Why Lira?

Fiber Concurrency

Lightweight green threads with simple spawn/await semantics. Write concurrent code without callback hell.

Pattern Matching

Expressive match expressions for control flow. Destructure data and handle variants elegantly.

Strong Typing

Catch errors at compile time with a powerful type system and full type inference.

Bytecode VM

Compiles to efficient bytecode. Fast startup, small binaries, and predictable performance.

Modern Tooling

LSP support, VS Code extension, syntax highlighting. Everything you need to be productive.

Clear Documentation

85+ examples, comprehensive language spec, and a standard library that's easy to learn.

See Lira in Action

fibers.li
// Spawn concurrent fibers
fn fetch_all(urls: [String]) -> [Response] {
    let fibers = urls.map(fn(url) {
        spawn { http_get(url) }
    })

    // Wait for all to complete
    return fibers.map(fn(f) { await(f) })
}

fn main() {
    let responses = fetch_all([
        "https://api.example.com/users",
        "https://api.example.com/posts",
    ])

    for resp in responses {
        println(resp.body)
    }
}

Lightweight Fibers

Spawn thousands of concurrent fibers without the overhead of OS threads. Lira's fiber scheduler handles the complexity while you write straightforward sequential code.

  • Simple spawn / await syntax
  • Automatic load balancing
  • No callback pyramids
match.li
enum Result<T, E> {
    Ok(T),
    Err(E),
}

fn parse_config(path: String) -> Result<Config, String> {
    match read_file(path) {
        Ok(content) => {
            match parse_json(content) {
                Ok(config) => Ok(config),
                Err(e) => Err("Invalid JSON: {e}"),
            }
        }
        Err(e) => Err("Cannot read file: {e}"),
    }
}

fn main() {
    match parse_config("app.json") {
        Ok(cfg) => println("Loaded: {cfg.name}"),
        Err(msg) => eprintln("Error: {msg}"),
    }
}

Exhaustive Matching

Pattern matching ensures you handle every case. The compiler catches missing branches before your code runs.

  • Destructure enums and structs
  • Guard clauses for complex conditions
  • Compile-time exhaustiveness checking
types.li
struct Point {
    x: Float,
    y: Float,
}

impl Point {
    fn distance(self, other: Point) -> Float {
        let dx = self.x - other.x
        let dy = self.y - other.y
        return (dx * dx + dy * dy).sqrt()
    }

    fn origin() -> Point {
        return Point { x: 0.0, y: 0.0 }
    }
}

fn main() {
    let p = Point { x: 3.0, y: 4.0 }
    let dist = p.distance(Point::origin())
    println("Distance from origin: {dist}")
}

Structs & Methods

Define custom types with associated methods. Type inference means you rarely need to annotate, but the compiler always knows.

  • Struct definitions with typed fields
  • Methods via impl blocks
  • Full type inference

Complete Toolchain

Everything you need to be productive, from day one.

lirac

Fast compiler with helpful error messages and type inference.

liravm

Lightweight bytecode VM with fiber scheduler and fast startup.

lira-lsp

Language server with completions, hover info, and go-to-definition.

lira-doc

Generate beautiful Markdown documentation from your code.