# Why Sakura Lang

URL: /docs/why-sakura-lang
Markdown: /docs/why-sakura-lang.md

> The problem with reviewing agent-written code, the thesis that the signature should be the contract, and the principles that follow from it.

## The problem [#the-problem]

AI agents now write a large share of new code, and that share is growing. The bottleneck has moved from writing code to trusting it.

The usual answer is code review, but reviewing diffs line by line does not scale when an agent can produce thousands of lines an hour. Reviewers skim. Skimming works only if the important facts about a change are easy to find, and in most languages they are not.

Four properties of mainstream languages make agent-written code risky to accept:

- **Exceptions.** Any call can throw, and nothing in the signature says what. A reviewer cannot tell which failures are handled without reading every callee.
- **Null.** A value that may be absent looks the same as one that is always present.
- **Ambient authority.** Any function in any dependency can open a socket, read an environment variable, or write a file. Supply-chain attacks rely on this.
- **Hidden IO.** A function named `format_price` might call a currency API. Nothing stops it, and nothing in the signature reveals it.

Agents make these problems sharper, not different. An agent will happily add a network call to a helper to make a test pass, catch and ignore an exception to silence an error, or interpolate a request parameter into a SQL string. Each change is small and plausible in a diff.

## The thesis [#the-thesis]

Make the signature the contract, and make the compiler enforce it.

In Sakura Lang, a function signature states what the function takes, what it returns, every effect it may perform, every error it may fail with, and the guarantees it makes about its result:

```sakura
fn signup(email: Email) -> User ! {Users, Clock, Random, Fail<SignupError>}
  ensures result.email == email
```

The body cannot perform an effect that is not listed or fail with a tag that is not listed; both are compile errors. The `ensures` clause is checked at runtime on every normal return, in every build mode.

This changes what review means. A human reviews the signatures, which are short and change rarely. The compiler checks the bodies, which are long and change constantly. When an agent's change needs a new effect, the signature has to change, and a signature change is exactly the thing a reviewer looks for. Compiler fixes that would widen authority or weaken a contract are never applied automatically.

## Why not an existing language [#why-not-an-existing-language]

Every language below is excellent at what it was designed for. None was designed for this workflow, and each shapes Sakura Lang in some way. The [prior art](/docs/prior-art) page lists, language by language, what Sakura Lang takes and what it rejects.

**TypeScript.** Huge ecosystem, fast feedback, and the language most agents write best today. But exceptions are untyped, any function can perform any IO, `any` and type assertions are one keystroke away, and there are several ways to do almost everything.

**Python.** The most readable mainstream language and a strong fit for scripts and data work. Types are optional and unchecked at runtime, exceptions and IO are invisible in signatures, and dependencies run with full authority at import time.

**Rust.** Proves that a language can be fast and memory safe without a garbage collector, and that a strict compiler with good diagnostics changes how people work. The cost is lifetimes and the borrow checker. Agents spend effort satisfying ownership rules unrelated to the task, and IO and panics are not tracked in signatures.

**Go.** Small, consistent, and quick to compile, with one toolchain and a formatter with no options. That simplicity is a direct inspiration. But errors can be discarded, nil remains, effects are untracked, and any package can reach the network.

**Effect-TS.** Brings typed errors and typed requirements to TypeScript, and shows that the model works for real services. It is a library on top of a language that cannot enforce it: plain TypeScript can still throw and still perform IO directly. Sakura Lang's `! {Users, Fail<E>}` is that model with no wrapper type, and it is the only way to write code.

**Koka, Unison, and Roc.** Koka contributed row-typed effects, effect-polymorphic higher-order functions, and Perceus reference counting. Unison contributed domain-named abilities with plain handlers and a compiler that speaks MCP; Sakura Lang keeps ordinary files and Git rather than a codebase database. Roc contributed platform-owned authority and in-place updates behind a value interface. Sakura Lang combines these with contracts, capabilities, `Untrusted`/`Secret` types, and machine-readable tooling, aimed at agents writing code for humans to review.

## Design principles [#design-principles]

These follow [design §1](https://github.com/icantcodefyi/sakura-lang/blob/master/docs/design.md).

### The signature is the contract [#the-signature-is-the-contract]

Parameter types with refinements, result type, effect row, error union, and `requires`/`ensures`: a reader can review a function from its signature alone. Every top-level function has a full signature; only local bindings are inferred.

### One way [#one-way]

One function syntax, one call syntax, one recovery construct (`try`/`catch`), one handler syntax (`with`), one absence type (`Option`), one failure protocol (`Fail<E>`), one formatter. No operator overloading, implicit conversions, macros, user-defined operators, or inheritance.

### Omission has one meaning [#omission-has-one-meaning]

A function type without `!` is pure. Missing cases, missing effects, and missing error handling are compile errors, never defaults.

### Diagnostics are an API [#diagnostics-are-an-api]

Every diagnostic has a stable code, byte spans, structured expected and actual values, causal links, and fixes that declare their impact. See [Diagnostics](/docs/agents/diagnostics).

### Honest guarantees [#honest-guarantees]

The compiler never prints "verified" for a program that merely compiled. Every claim about a program has exactly one status:

| Status | Meaning | Established by |
| --- | --- | --- |
| `proved` | Holds on all executions under the stated assumptions. | The type and effect checker; later, SMT-discharged contracts. |
| `runtime_checked` | Violations are detected at the boundary and become a defect. | Contract lowering, checked arithmetic, checked refinements. |
| `tested` | Held on the executed inputs. | `sakura test`. |
| `trusted` | Assumed. | FFI, host handlers, `@trust` sites, the toolchain itself. |

The type system proves that every performed effect has a handler, every `Fail` tag is caught or declared, every `match` is exhaustive, no value is null, no index is unchecked, a `Secret` is never shown, and a capability cannot be forged. It does not prove business correctness, termination, or that the specification is the right one.

### Compiler owns memory [#compiler-owns-memory]

No lifetimes, borrow annotations, or `Rc` in user code. The price is a restricted data model (no aliasable mutation, no cycles) and explicit resource scopes.

## Non-goals for v0 [#non-goals-for-v0]

- Multi-shot or non-tail-resumptive handlers, `resume`, first-class continuations.
- An `Async` effect or a sync/async split in source.
- User-defined traits or interfaces. A fixed set of derived constraints (`Eq`, `Ord`, `Hash`, `Show`, `Schema`) covers v0.
- Higher-rank types, GADTs, type-level computation.
- Information-flow control. `Secret<T>` prevents accidental disclosure, not deliberate leakage.
- Automatic termination proofs.
- Durable workflows, a distributed runtime, or a UI engine. These are later packages.
- A tracing GC on native or WASM.

## Next [#next]

Read the [Quickstart](/docs/quickstart) preview, or go straight to the [Language Tour](/docs/tour/basics).
