Tessera

Small on purpose

Tessera has Int, Bool, Text, Unit, List, Map, Option, Result, Decimal and Bytes, plus your own records and enums with exhaustive match. There are no implicit conversions, no shadowing, no overloading and no methods: one name, one signature.

Errors are values. A function that can fail returns a Result or an Option, and try passes the failure on to the caller.

Enums and exhaustive match

shapes.tes
enum Shape {
    Circle(radius: Int)
    Square(side: Int)
    Empty
}

fn area(shape: Shape) -> Int {
    match shape {
        .Circle(radius) => 3 * radius * radius
        .Square(side) => side * side
        .Empty => 0
    }
}

Effects are part of the signature

A function that touches the outside world must say so with uses. The effects include io, fs, env, time, random, log, db and net, and a function may only call functions whose effects it declares. A function without uses is pure: it cannot print, read a file, query a database or open a connection.

Declaring an effect that is never used is an error too, so a signature cannot quietly overstate what the code does.

effects.tes
type Visit {
    path: Text
    status: Int
}

// No `uses`: this function is pure.
fn describe(visit: Visit) -> Text = "\(visit.status) \(visit.path)"

// `uses db`: this function may talk to the database, and nothing else.
fn save(db: Database, visit: Visit) -> Result[Int, Text] uses db {
    db_execute(db, "INSERT INTO hits (path, status) VALUES (?1, ?2)", [visit.path, to_text(visit.status)])
}

Safe by default

The checks that make a program easier to trust.

Bounds-checked lists

Indexing outside a list stops the program with a clear runtime error instead of reading arbitrary memory.

Checked arithmetic

Integer overflow and division by zero are runtime errors, never silent wrap-around.

Stable error codes

Compiler errors such as E0301 and runtime errors such as R001 have fixed codes, and usually a help: line. That suits people and models alike.

No unsafe code

Generated programs carry #![forbid(unsafe_code)], so the Rust compiler rejects unsafe code in them.

Notes

note "..." attaches design intent to the next function. Notes never change behaviour, and the tooling exports them.

Exact decimals

Decimal is an exact number with nine decimal places, so prices and totals do not drift like floating point.

One canonical layout

Indentation has no meaning in Tessera, and the formatter rewrites source into one canonical layout without it, which saves tokens. The samples on this site are indented only for people. The source of this site itself is in the canonical layout.

Read the specification

The language design document is the authoritative description. When the compiler and the document disagree, the document wins.

Language design on GitHub How it works