A Programming Language with No Compiler
A programming language with no compiler. No interpreter. No runtime. Just a specification, 86 tests, and an AI agent. The compiler is you, talking to a machine.
There’s a concept gaining traction in AI engineering circles: the ghost library — software distributed as a specification rather than code. No package manager. No dependency. Just a spec and a set of tests. You hand both to an AI agent, and it builds the implementation in whatever language you need.
It’s a clever idea. But a library is small. A handful of functions. A few hundred lines of spec.
What if you went further? What if the spec didn’t describe a utility — but an entire programming language?
A Language Where the Syntax Is English
I recently wrote about Jensen Huang’s claim that human language is the best programming language. The CEO of NVIDIA — the company whose GPUs power every major AI model — described a future where you tell a computer what you want in plain English, and it just does it.
So I built that future. Meet humanlang — a programming language with no compiler.
No interpreter. No runtime. No binary. Just a specification and 86 test cases. You give both to an AI agent, and it builds a working interpreter in whatever language you choose.
But here’s the twist: the syntax of the language itself is natural English.
This is what FizzBuzz looks like in humanlang:
-- FizzBuzz in humanlang
for n from 1 to 100:
if n modulo 15 is equal to 0:
print "FizzBuzz"
otherwise if n modulo 3 is equal to 0:
print "Fizz"
otherwise if n modulo 5 is equal to 0:
print "Buzz"
otherwise:
print n
No semicolons. No curly braces. No && or || or !=. Just English words arranged into logic.
What’s in the Repo
The humanlang repository contains:
| File | Purpose |
|---|---|
SPEC.md |
Complete language specification with EBNF grammar |
tests.yaml |
86 language-agnostic test cases |
INSTALL.md |
Build instructions (a prompt) |
examples/ |
Sample humanlang programs |
kotlin/ |
AI-generated Kotlin interpreter (1,332 lines) |
rust/ |
AI-generated Rust interpreter (2,103 lines) |
ocaml/ |
AI-generated OCaml interpreter (1,429 lines) |
zig/ |
AI-generated Zig interpreter (1,741 lines) |
haskell/ |
AI-generated Haskell interpreter (1,243 lines) |
asm/ |
AI-generated ARM64 assembly interpreter (5,271 lines) |
What’s not in the repo: hand-written code. Not a single line. Every interpreter was generated entirely by AI agents reading the spec.
The installation instructions are a prompt:
Build a humanlang interpreter in [LANGUAGE].
1. Read SPEC.md for the complete language specification
2. Parse tests.yaml and generate a test file
3. Implement a lexer, parser, and tree-walk interpreter
4. The entry point should accept a .hl file path as a command-line argument
5. Run tests until all pass
6. Place implementation in [LOCATION]
Pick your language. Pick your location. Copy, paste, go.
More Than a Gimmick
humanlang is a complete programming language. Variables, arithmetic, strings, booleans, lists, conditionals, loops, functions, recursion, type conversion. Here’s a recursive factorial:
define factorial with n:
if n is at most 1:
return 1
return n times (call factorial with (n minus 1))
print call factorial with 10
And here’s a function that filters even numbers from a list:
define is_even with n:
return n modulo 2 is equal to 0
define filter_even with numbers:
set result to []
for each n in numbers:
if call is_even with n:
append n to result
return result
set evens to call filter_even with [1, 2, 3, 4, 5, 6, 7, 8]
print evens
Output: [2, 4, 6, 8]. A working program, written in sentences.
Spec-Driven to the Core
This is spec-driven agentic development taken to its logical extreme. When I wrote about OpenSpec and the idea that you should write the spec first, review it, freeze it, then let an AI agent build — I was talking about features and APIs. But the same principle applies to something far more fundamental: an entire programming language.
The SPEC.md file is 400 lines. It defines every data type, every operator, every control flow construct, and a complete EBNF grammar. The tests.yaml file contains 86 test cases covering everything from basic printing to recursive functions to FizzBuzz.
Give both files to Claude, Codex, or any capable AI agent. Ask for a Python interpreter. Or Rust. Or Go. Or TypeScript. The spec is language-agnostic. The tests are language-agnostic. The implementation adapts to whatever you need. To prove it, I did exactly that — multiple times, across radically different paradigms.
The Proof
I gave Claude Code the same SPEC.md and tests.yaml repeatedly. Same spec. Same 86 tests. Different languages. Different paradigms.
| Language | Paradigm | Lines | Build |
|---|---|---|---|
| Kotlin | JVM / OOP + Functional | 1,332 | kotlinc humanlang.kt -include-runtime -d humanlang.jar |
| Rust | Systems / Ownership model | 2,103 | cargo build --release |
| OCaml | Functional / Algebraic data types | 1,429 | ocamlopt -o humanlang humanlang.ml |
| Zig | Manual memory / Zero overhead | 1,741 | zig build -Doptimize=ReleaseSafe |
| Haskell | Pure lazy functional | 1,243 | ghc -O2 -o humanlang Main.hs |
| ARM64 Assembly | Raw machine instructions | 5,271 | cc -o humanlang humanlang.s |
Thousands of lines of working code, generated from a 400-line spec. Each interpreter — lexer, parser, tree-walk executor — was built by an AI agent reading the specification and iterating until all 86 tests passed. No human wrote a single line.
Kotlin because it’s the modern JVM workhorse. Rust because its ownership model is about as far from “just parse some strings” as you can get. OCaml because it’s the functional language that programming language researchers actually use. Zig because there’s no garbage collector, no hidden allocations — you manage every byte yourself. Haskell because building a mutable, stateful interpreter in a language that philosophically opposes mutation is the ultimate stress test. And ARM64 assembly because — honestly — we wanted to see if it was even possible. 5,271 lines of raw machine instructions, calling libc for I/O and memory, everything else by hand. If the spec holds across every paradigm, it holds.
The implementations are in the repo. Clone it. Run run_tests.sh in any of the directories. 86/86. Every time.
From Ghost Libraries to Ghost Languages
A ghost library replaces a dependency. You don’t install a package — you describe what the package should do, and an AI builds it locally.
humanlang takes this further. A programming language is orders of magnitude more complex than a utility library. It has a grammar, a type system, scoping rules, control flow, recursion. And yet — it fits in a spec that any modern AI agent can implement from scratch.
If a ghost library replaces a dependency, a ghost language replaces a compiler.
The Quiet Revolution
Something is happening that most people haven’t fully processed yet.
We used to distribute software as binaries. Then as source code. Then as packages. Now we can distribute it as descriptions. A well-written spec and a comprehensive test suite are enough. The AI fills in everything else.
Human language isn’t just becoming the best way to write code. It’s becoming the best way to distribute code.
The repo is here: github.com/vpetreski/humanlang. Clone it. Give the spec to your favorite AI agent. Watch it build a programming language from a document.
Then ask yourself what else we’ve been over-engineering all this time.
Related Reading
Human Language Is the Best Programming Language
Spec-Driven Agentic Development
Decade Zero: A Realistic Blueprint for 2026–2035