Fortis

A programming language · v0.0.1 release candidate

Written by AI.
Reviewed by people.

Fortis is a statically checked, compiled language for software written mostly by AI agents. People can read, review and trust it because every decision is written in the source. Ownership, changes, failures and effects are explicit.

Decisions you can point to.

Hover or focus a note, line or pin to explore. Click or tap to pin the focus; repeat, click elsewhere or press Escape to clear. Go to the notes.

mean.ftFORTIS / Complete program · 28 lines
import fortis.host { Host }export error Empty {  code: "demo.empty"}123pure try func mean(readings: ListView[Int<0..1000>]) Int {  let n = readings.count()  if n <= 0 {    fail Empty()  }  let mut total = 0  for r in readings {4    total = Int.add(total, r) or fail  }  return total / n}export func main(args: List[String]) Void {7  let caps = Host.capabilities()5  let mut readings: List[Int<0..1000>] = List.of(12, 30, 18)5  editable readings.push(40)6  let m = mean(readings) catch e {6    report e6    recover 0  }7  caps.console.print("mean of ${readings.count()} readings: ${m}")}
Fortis · UTF-8Source pins ↔ review notes
Outputfortis run mean.ft
mean of 4 readings: 25
Same output on the interpreter, the VM and native
  1. Checked purity

    pure rules out effects such as I/O and clock access. The checker verifies it.

  2. Declared failure

    try declares that mean can fail. Its caller must handle the outcome.

  3. Bounded input

    Int<0..1000> carries a range. ListView gives read-only access.

  4. Visible propagation

    Int.add checks overflow. or fail passes the failure to the caller.

  5. Explicit changes

    mut declares a mutable binding. editable marks the call that changes the list.

  6. Caller’s recovery

    catch handles the failure, reports it and recovers with 0.

  7. Host authority

    main obtains capabilities from the host. Printing uses the console capability.

Example source. This example is checked and run on all three backends when the documentation builds.

Try this program locally.

Start with a checkout of the Fortis repository. You need Python 3 and a Rust toolchain with cargo. Run these commands from the repository root.

  1. Build the tools

    The reference toolchain uses Python. Build the production compiler with Cargo.

    cargo build --release --manifest-path compiler/Cargo.toml
  2. Save the example

    Copy the complete program above and save it as mean.ft in the repository root.

    The copy includes only the source, without line numbers or annotations.

  3. Check and run

    Check the source, then run it on the reference interpreter.

    bin/fortis check mean.ft
    bin/fortis run mean.ft
    Outputbin/fortis run mean.ft
    mean of 4 readings: 25
    Same output on the interpreter, the VM and native

v0.0.1 release candidate. Language 1.0 is still being built and is not released.

What a reviewer can check.

Fortis puts ownership, failure handling and authority in the file or diff you are reading.

Who owns a value

Every value has one owner. Loans and moves are checked. Cleanup runs exactly once, at a visible point.

Who handles a failure

A call that can fail says so. Each failure must be handled, reported or passed up. The compiler checks this.

What a function can do

The checker verifies pure. Output needs a console capability obtained from the host.

One program. Three backends.

The interpreter, development VM and native backend must agree on program output. The test suite checks that agreement.

Reference interpreter

The reference for what a program means.

bin/fortis run mean.ft

Development VM

Run with the production compiler's VM.

compiler/target/release/fortisc vm mean.ft

Native executable

Compile through a safe Rust crate.

bin/fortis build mean.ft --out mean

Where Fortis stands.

The current status is v0.0.1 release candidate. Each release is a subset with its own documentation and release checks. Performance is judged at v1.0.

  1. v0.0.1 · nowWrite, check, run, build, format and test programs. Modules, functions, classes, enums, ownership and failures.
See the planned releases through v1.0
  1. v0.0.2Source conventions. Fewer markers, capabilities as parameters and built-in logging.
  2. v0.1Domain modelling. Interfaces, generics, refinements and contracts.
  3. v0.2Effects and testing. Checked effects, property tests and packages with dependencies.
  4. v0.3Concurrency. Async, tasks and structured concurrency.
  5. v0.4Standard library. Collections, text, Unicode and numerics.
  6. v0.5–0.6Production tooling. Observation, runtime, kits and an incremental compiler.
  7. v1.0Stability. Editions, migration and a stability promise. Performance judged against Rust.