A language for the age of agents

“Heroes”

Decades of programming-language history, condensed into fewer than 16K tokens.

It reads like Python and has all the power of C. Many of the mistakes LLMs make, the AI models that write code, simply don’t compile here. No braces, no semicolons. No interpreter, no virtual machine. No null in your own types, no exceptions. No garbage collector, no heavy runtime. Mature enough to compile its own compiler. Small enough to fit in a prompt. What you write becomes a standalone executable.

examples/gallery/02-tokens.hero
variant Token
    number
        value: i64
    word
        text: str
    plus
    times
    open
    close

# What a token is called in a message.
function name_of(t: Token) -> str
    return match t
        .number _ => "a number"
        .word _   => "a word"
        .plus     => "`+`"
        .times    => "`*`"
        .open     => "`(`"
        .close    => "`)`"

leave a case out and it does not compile · read the example →

The count behind the 16K is the model’s own, taken through Claude’s token-counting API and recorded with the model that produced it; a test holds the specification under that ceiling on every commit.

The whole language, in one file: curl -L heroes-lang.org/spec.md

The compiler reports mistakes

A model writes totl instead of total. In languages that let an assignment declare a variable, a typo like this can create a new variable. Heroes uses different syntax for declaring and updating variables: the compiler rejects the unknown name and suggests a correction:

error[unknown_name]: nothing named `totl` is in scope — did you mean `total`?
  at tests/golden/check/typo-not-a-new-binding.hero:10:9
     |
  10 |         totl @ total + x  #~ unknown_name
     |         ^^^^
  fix (certain): rename to `total`

The compiler also catches swapped labelled arguments, missing cases and keywords from other languages. Each message identifies the problem and its location in the code. When possible, it suggests a fix; fixes marked certain can be applied automatically. More error examples →

Heroes uses C libraries

Heroes uses C libraries for maths, files, sockets, databases and graphics. A few lines declare the library functions your program needs. Clang, the C compiler, checks these declarations against the library’s header, the file that describes its functions and types. If the types do not match, compilation stops.

extern "math.h" link "m"
    function sqrt(x: f64) -> f64
    function pow(base: f64, exponent: f64) -> f64
    function floor(x: f64) -> f64
examples/gallery/08-ffi.hero, lines 12–15

The examples include programs that use a database, call a graphics library and send a web request. Their pages also show recorded output where available. Examples using C libraries →

The thesis

A language designed so that every plausible LLM mistake is a compile error will produce working programs in fewer total tokens than a conventional language, even if each program costs more tokens to write.

One part of the thesis has been tested. heroes mutate introduces one realistic mistake at a time into working programs and counts how many the compiler catches. It repeats the run with the Heroes-specific checks switched off. The rules that require an argument’s name and refuse a reused one carry the difference: with them off, those mistakes compile. The same table names the mistakes no check catches.

The other part is the total number of tokens a working program costs, corrections included, with the Heroes-specific checks on and with them off. The instrument that measures it has run once, on tasks written and sealed before the run, under a prediction published first. With the Heroes-specific checks and without them, the models solved the same tasks within three tries: for the experiment, that result is called inconclusive. The figures are stated at the publication gate. A comparison with other languages comes after it. What is measured → The available results →

Run it · speed of life ·

Heroes is in beta: the language still changes. The version you build below is heroes 0.5.0. Until 1.0.0, a change in the middle number can change the language itself, and a change in the last number never does. A program you write today may need small edits later.

$ git clone https://github.com/heroes-lang/heroes
$ cd heroes
$ clang -I runtime seed/heroes.c runtime/runtime.c -o heroes
$ ./heroes run examples/gallery/03-fallible.hero
read 42
failed: not_a_digit (expected 0-9)
20

The third line builds the compiler from a single C file. It takes under four seconds on a MacBook Air, the machine every measurement here comes from. The Heroes compiler generated that C file, so clang is all you need. The line saying failed is the example refusing a character it cannot read. The getting started guide → · the language, one idea at a time →

Who is building it

One person and an AI assistant. The person had never seriously written a compiler before this one, but had studied the history of programming languages and their compilers, and the book below came out of that study. The assistant follows rules stored in the repository, the project’s archive. A panel of five judges reviews every language change; four can veto it. The author approves or rejects each decision. Who wrote this → · how changes are reviewed →