Baseline

A fast, safe functional language that's easy to learn and hard to break, whether you write the code or use an AI agent.

fn fetch_user!(id: Int) -> {Http, Console} Result<String, String> =
  Console.print!("Fetching user ${id}")
  let response = Http.get!("/users/${id}")?
  match response.status
    200 -> Ok(response.body)
    404 -> Err("User not found")
    code -> Err("HTTP ${code}")

You can read this function's entire contract from the first line:

Remove {Http} from the declaration and the compiler rejects the program.

Designed for AI Agents

AI agents generate code fast but make subtle mistakes: invalid states, hidden side effects, unchecked errors. Most type systems either catch too little to help or require formal proofs that agents can't produce. Baseline finds a middle ground: types that check real constraints, like rejecting a port number of -1 at compile time, without needing formal verification expertise.

Many languages let you do the same thing in several ways. They hide side effects in functions that look safe and rely on runtime checks that can be missed. That's manageable when people review every line, but it breaks down when agents generate code at scale.

Baseline uses one syntax for each concept, so agents don't waste tokens choosing between equivalent alternatives. Effects appear in every function signature, making dependencies obvious. Constraints are checked before the code runs. The compiler gives structured JSON diagnostics that agents can parse and fix in a single pass.

Read the full design →

Types as Specs

Refinement types let you state a constraint once. The compiler proves it at every call site. No runtime validation code to forget.

type Port = Int where self >= 1 && self <= 65535
type Percentage = Int where self >= 0 && self <= 100
type PositiveInt = Int where self > 0

fn listen(port: Port) -> Unit =
  // port is guaranteed 1..65535. No validation needed.
  ...

No null, no exceptions, no undefined. You model your domain with algebraic types and the compiler holds you to it.

type Connection =
  | Disconnected
  | Connected(Socket)
  | Error(String)

fn status(conn: Connection) -> String =
  match conn
    Disconnected      -> "offline"
    Connected(_)     -> "online"
    Error(msg)       -> "error: ${msg}"

More on types →

Effects as Permissions

Side effects go in the type signature. If a function doesn't declare {Fs}, it can't touch the filesystem. No {Http} means no network requests. The compiler enforces this, not a linter.

// Pure: no effects, no surprises
fn add(a: Int, b: Int) -> Int = a + b

// Effectful: declares exactly what it does
fn save!(data: String) -> {Fs} Unit =
  Fs.write!("out.txt", data)

Built-in effects:

ConsoleTerminal I/OHttpNetwork requests
FsFilesystemRandomRandom numbers
EnvEnvironment varsSqliteDatabase
LogLogging (ambient)TimeClock (ambient)

Want to sandbox AI-generated code? Grant {Console} but withhold {Fs} and {Http}. The type system is the sandbox.

More on effects →

One Way to Do Each Thing

There's one syntax per operation. Not a style guide, the grammar itself. One way to chain, one way to handle errors, one way to call functions.

ConceptBaselineNot supported
Chainingx |> f |> gmethod chaining, composition
ErrorsResult<T, E> + ?try/catch, exceptions
OptionalsOption<T>null, undefined, nil
CallsModule.fn(value)value.method()
Negationnot x!x
Concat"${a}${b}"a + b

Machine-Readable Diagnostics

The compiler outputs structured JSON: source locations, error codes, and fix suggestions with confidence scores. AI agents don't need to scrape error messages, they get machine-readable diagnostics.

$ blc check app.bl --json
{
  "status": "failure",
  "diagnostics": [{
    "code": "TYP_002",
    "message": "Undefined variable `nme`",
    "suggestions": [{
      "description": "Did you mean `name`?",
      "confidence": 0.8
    }]
  }]
}

The agent loop: load llms.txt, generate code, run blc check --json, apply fixes, repeat. Since there's only one way to write each construct, the agent doesn't waste tokens choosing between equivalent alternatives.

Get started GitHub