lova-lang
Health Warn
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Pass
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Every language before it was built for humans to read and learn. LOVA is the first built for AI: programs are integer sequences — 64 one-byte operators, structured faults with repair hints, declared effects, budgets, lineage, a Rust VM at 11M steps/s, an MCP server. Open source: extend, modify or rebuild it to make AI faster.
LOVA
English · 中文
An AI-native integer-sequence programming language.
Site: npcnpc09.github.io/lova-lang — the language in one page, on a field of a quarter million particles (docs/).
Status: 1.0 — the language is complete, and initially usable.
All ten design axioms are realised inside the language and measured by
an experiment. The 64-operator table is spent (63 operators and END):
integers, lists, strings, closures, letrec, loops, error handling
that can catch and raise, programs as values with lineage, populations
that evolve, file / clock / network IO under declared capability
boundaries, and a persistent map. There is a compiler with five static
passes, a type-constrained generator, a standard library written in
LOVA, modules, a CLI, an MCP server for agents, and 1 104 tests. The
reference implementation is a stdlib-only Python interpreter; the
programs run on a native Rust runtime -- a bytecode VM at 10-12
million steps a second, checked against the interpreter step for step
on a golden set of 1 023 records -- which is the default, and the same
runtime loads into Godot 4 as an extension class, so a game's rules can
be LOVA under the engine's own picture. It has no floats, no namespaces
and no concurrency. The "What LOVA still cannot do" section below is
kept honest.
The one-paragraph pitch
Every programming language before it was built for a person -- to be
learned by a human, read by a human, reviewed by a human. LOVA is the
first built for an AI.
LOVA has one goal: an AI uses it more conveniently than any other
language. Not denser, not stranger: fewer attempts from writing to
running, less context spent on each failure, no scaffolding needed to
run the code safely, and code that can be reused, repaired and traced
by the program that comes after it. The error model, the contracts, the
declared effects, the lineage and the evolution machinery exist for
that; the integer encoding underneath is the format and the identity
of a program, not the point. AI is the first-class reader, writer,
and executor -- and the people who work with it are the second.
And because it is open source, the language is not anyone's to own.
Anyone may extend it, change it, or rebuild it outright -- on the one
test that decides everything here: does an AI get more done with it,
and get it done more easily.
(defn square [n] (⊗ n n))
(square 7)
...is a Stage-1 projection. The program itself is an integer sequence;
the text is a pretty-printer over it. ⊗ is mul, defn desugars tolet + lambda, and the call desugars to apply — so what the
substrate stores is:
(let 0 (lambda 1 (mul (ref 1) (ref 1))) (apply (ref 0) 7))
Identifiers are interned to integer name ids at parse time and printed
back as integers, because the integer is the program (Axiom 1). Every
form above compiles to the existing 64 operators; the sugar adds no
semantics.
Three stages
| Stage | Surface | Status |
|---|---|---|
| 1 — Text-surface LOVA | Lisp-like s-expressions compiling 1:1 to tokens | current, and now audit-oriented |
| 2 — AI-primary LOVA | one character per byte, no delimiters (core/surface2.py) |
surface built and measured (Exp 14); fine-tuned model still M8 |
| 3 — Pure-AI LOVA | no text; programs are integer sequences, humans read via (explain program) |
north star |
What's actually implemented
- 64-token core ISA (8 families × 8), 1 byte per operator — 52 operators
have runtime semantics, 12 are reserved (spec/tokens.md, generated
from the table byspec/generate_tokens_md.py) - Data — one cons cell (
nil/cons/head/tail/nil?)
gives pairs, lists, and strings as codepoint lists, so"abc"is
surface sugar and costs the token table nothing (spec/token-budget.md) - Two surfaces — Stage 1 s-expressions for authoring and audit, and
the Stage-2 projection of the byte encoding for density: one character
per byte, no delimiters, lossless in both directions
(core/surface2.py) - IO —
stdout/stdin, the first operators that touch the world;
the only non-determinism in the language, andstatic_analyzereports it - A standard library written in LOVA —
lib/prelude.lova:map,filter,fold,range,append,reverse,digits,printlnand
the rest, none of them builtins. Free to include: the compiler'sdrop-unusedpass takes a program that calls none of it from 474 nodes
back to 1 - A command line —
lova run | repl | emit | analyze | mcp
(core/cli.py) - An MCP server —
lova mcpserveslova_execute,lova_static_analyze,lova_valid_nextandlova_emitto any
Model-Context-Protocol host over stdio, with no dependency outside the
standard library;lova_valid_nextis Axiom 3 as a service
(core/mcp_server.py) - One error model, reachable from inside — every fault carries the
same structured anomaly, and(when-anomaly body handler)hands a
program the anomaly's code so it can recover. The substrate's
termination ceiling is the one thing a program cannot mask - Populations — Axiom 6 in the language:
(defpop scorer p1 p2 …)
builds a pool,(evolve pop)runs a generation with the same rule the
Python engine used,(select pop 0)is the fittest, and the winner
can say where it came from. Exp 15 re-runs the self-healing experiment
as one LOVA program - Programs as values —
quote/eval, and the whole Meta family:(explain p)renders a program as text,(hash p)gives its integer,(why p)/(lineage-query p)/(ancestor-of a b)ask where it
came from,(clone p)/(mutate p 30)derive one and record how,
and(read text)isexplain's inverse, so a program can build a
program from text andevalit. Axiom 5 is now true inside the
language, and Stage 3'sexplainexists - The world, declared —
(boundary "fs-read clock" body)says
which effectsbodymay use;fs-read/fs-write/clockare
the effects. The compiler refuses a use outside a boundary that
declares it, the runtime refuses a boundary the host did not grant
(lova run --allow fs-read,clock), nothing is granted by default,
and a generated program cannot use the world without declaring it.
The network isnet-send/net-recvover UDP datagrams: the
program declares the kind, the host names the places (--allow net=host:port,net=:port). Axiom 4, for effects that touch the
world - A standard library a program can stand on — lists that iterate
rather than recurse (len/map/filter/fold/sort/take/zip...), text (words/lines/split/join/parse-int/text-of), a persistent map (map-put/map-get/map-pairs, keys integers or text), andsignalso a
library can raise the structured anomaly its callers can catch.apps/wordfreq.lovais the acceptance program (M22) - Libraries —
(use "evolution")includeslib/evolution.lova,
where a custom evolution rule is nine lines over the six Evolution
operators;(use "prelude")is the standard library, loaded by the
CLI by default. Inclusion is textual, once, and free afterdrop-unused - Abstraction — unary closures with currying,
letrec, and a loop
combinator, so recursion and unbounded iteration are expressible.
Two always-on ceilings (MAX_CALL_DEPTH,MAX_STEPS) turn
non-termination into a structured anomaly rather than a hang
(core/runtime.py) - Type-directed generation — for any partial program the set of
well-typed next tokens is computable, so ill-typed programs are not
representable (core/types.py,core/generator.py) - Conservation as a type — budget/effect bounds live in the signature;
violations are compile errors or runtime Δ-traps (core/conservation.py) - Surprise instead of stack traces — deviations surface as structured
anomalies; the Δ-trap scanner pinpoints the deepest offending
sub-expression and the correction value (core/runtime.py) - Lineage — every artifact carries provenance, queryable in-language
(core/lineage.py) - Populations — a function is a pool of competing variants, not a
single definition (core/populations.py) - Compiler — scope-check, type-check, constant-fold passes; compile
errors share the runtime anomaly schema so an agent has one error
handler (core/compiler.py) - LOVABench — 60 tasks / 180 cases across 5 categories, with a
reference evaluator (corpus/). Note: every task predates M9, so
none of them exercises recursion or iteration (Q33).
Quick start
Requires Python ≥ 3.10. The core has no dependencies, so it also
runs under PyPy. With Rust installed, cargo build --release innative/lova-rt builds the native runtime -- 10-12 million steps a
second, twenty times CPython -- and lova run uses it by itself for every program it
implements (--native off for the Python runtime, --native on to be
told why it could not be used): the same values, the same anomalies,
the same step counts, checked record by record againstcorpus/golden/. The compiled program is cached under $LOVA_CACHE,
or %LOCALAPPDATA%\lova\cache on Windows and ~/.cache/lova
elsewhere, keyed by the source, the libraries it uses and a hash of
the implementation, so a second run of a program that pulls in one of
the 3D libraries skips a parse that costs one to two seconds;LOVA_CACHE=off disables it.
git clone <this-repo> lova && cd lova
export PYTHONPATH="$PWD"
# run a program
python -m core.cli run apps/is_prime.lova 1999 # => 1
python -m core.cli run apps/palindrome.lova racecar # => 1
python -m core.cli run apps/palindrome.lova 's="7"' # a quoted argument is a text, even "7"
# play noughts and crosses against a negamax that never loses
python -m core.cli run apps/tictactoe.lova 0
# run untrusted programs, one per line, under a budget; report each by name
python -m core.cli run apps/sandbox.lova 5000 < programs.txt
# evolve a pool of programs toward a target and ask the winner why it exists
python -m core.cli run apps/evolve.lova 42 60
# repair a program that violates its contract, guided by surprise
python -m core.cli run apps/repair.lova 42 30 200
# a Python web shell whose only decision is a LOVA rule you can edit and break
python apps/shell/policy_app.py # http://127.0.0.1:8765
# tank battle: the window is Python, every rule of the game is LOVA
python apps/tanks/tank_game.py # arrows move, space fires
python -m core.cli run apps/tanks.lova 7 # the same game, turn by turn in the terminal
python apps/g2048/game2048.py 7 # 2048, ported from gabrielecirulli/2048
python apps/platformer/platformer.py # Kenney's 3D platformer kit, ported out of GDScript
python apps/fps/fps.py # Kenney's FPS kit: two blasters, four flying enemies
# the two kits above draw in an SDL window when pygame is there
# (`pip install pygame` for the smooth window; Tk is the fallback, and
# `--host tk` / `--host sdl` chooses. `--bench N` prints frame times)
python apps/godot/fps/build.py path/to/Starter-Kit-FPS --run # the FPS kit's rules inside Godot
# an interactive session, with the standard library loaded
python -m core.cli repl
# see a program as the Stage-2 surface, as bytes, or as one integer
python -m core.cli emit apps/coprime.lova 14 15 --form stage2
python -m core.cli emit apps/coprime.lova 14 15 --form int
# what will this program do, without running it
python -m core.cli analyze apps/collatz.lova 27
# run the examples a program declares about itself
python -m core.cli check apps/tictactoe.lova 0
# run the test suite (1 104 tests, stdlib unittest only)
python -m unittest discover -s tests
# the same under PyPy, where the whole suite is also expected to pass
pypy -m unittest discover -s tests -t .
# run an experiment
python experiments/experiment_01_hello_lova.py
# the per-app Python drivers still work, and print the whole pipeline
# (parse → analyse → compile → encode → evaluate)
python apps/is_perfect.py 28
Or install it — the wheel ships the core, the LOVA libraries and the
corpus, and puts a lova command on the path:
pip install .
lova run apps/is_prime.lova 1999
Give it to an agent
lova mcp speaks the Model Context Protocol on stdin/stdout. Any MCP
host — Claude Code, Claude Desktop, Cursor — gets four tools: run a
program (with explicit capability grants), analyse one without running
it, ask which tokens may come next in a partial program, and project a
program into Stage 2 / bytes / one integer.
{"mcpServers": {"lova": {"command": "lova", "args": ["mcp"]}}}
From a checkout without installing: "command": "python", "args": ["-m", "core.cli", "mcp"], "cwd": "/path/to/lova-lang".apps/mcp_demo.py drives the server through its pipes and calls each
tool once.
All 14 experiments run. Exp 03 and Exp 07 had been dead since the
corpus grew from 20 tasks to 60; they were fixed at M13 and their
numbers below are the 60-task ones.
Experiment 11 additionally needs tiktoken:
pip install -e ".[experiments]"
What the programs show
Twenty-three programs in apps/, each written to use the language for
something and kept as a test. What they demonstrate:
It runs a game. Tank battle, in real time: eight enemies arrive
along the top of the grid, wander until they see you or your base
down a clear line, and shoot. Every rule -- movement, walls a bullet
breaks, the enemies' aim, spawning, the win -- islib/tanks.lova,
about 250 lines of pure functions over one world record, carrying
eighteen examples of itself thatlova checkruns. The window is
tkinter and owns nothing but the pixels and the keys: ten times a
second it hands the LOVA program the world and the key you hold, gets
the next world back, and paints it. A turn costs about 10 000 steps
under a budget of 200 000, shown in the corner, and a rule that ran
away would be a structured anomaly on the screen rather than a frozen
window. The same rules play turn by turn in a terminal.
python apps/tanks/tank_game.py # arrows move, space fires, R restarts python -m core.cli run apps/tanks.lova 7 # the terminalIt ports someone else’s game, and proves it. 2048, after
gabrielecirulli/2048 (MIT):lib/g2048.lovawas written against the original’sjs/game_manager.js— the same traversal order, the same
farthest-position walk, the same rule that a tile made this move
cannot merge again, the same score, the same nine-in-ten chance of a
two. The claim that a port behaves like its original is not made in
prose:tests/test_2048.pyholds a transliteration of the original
in Python and runs both over random positions, comparing the board
cell by cell. 10 000 positions, no disagreement. One difference
on purpose — the original’s chance isMath.randomand cannot be
replayed; here the generator is threaded through the world, so a seed
is a game. The port also found a real bug in our own compiler, in
whatdrop-unuseddoes with a binding kept for its effects.
python apps/g2048/game2048.py 7 # the window, in the original's colours python -m core.cli run apps/g2048.lova 7 # the terminalAnd a 3D platformer, ported from Kenney's starter kit.
lib/platformer.lovaholds the rules of
KenneyNL/Starter-Kit-3D-Platformer
(MIT, about 1 200 stars), written against its GDScript: the character
that walks, jumps twice and squashes when it lands, the coins that
bob and spin, the platforms that give way, the bricks broken from
below, the camera that follows, turns and zooms, and the fall off the
world that starts everything again — every constant the kit's own.lib/scene3d.lovaputs the kit's models into one picture under a
camera that moves: forty-six objects placed, turned, tilted, culled
and lit, about 4 000 LOVA steps a tick and 150 000 a frame. The
models and the level are the kit's, read out of its.glbfiles and
its scene byapps/platformer/import_kit.pyand decimated to a
budget each with the paint kept where it was.tests/test_platformer.py
transliterates the kit's five scripts and runs them beside the port
one tick at a time over a scripted play: every position within four
thousandths of a metre, the same coins taken, and the fall off the
world on the same tick.
python apps/platformer/platformer.py # WASD, space, arrows, +/- python apps/platformer/platformer.py --shot out.png # one frame, no windowAnd a first-person shooter, from Kenney's FPS starter kit.
lib/fps.lovaholds the rules of
KenneyNL/Starter-Kit-FPS
(MIT, about 1 000 stars): a player who walks at five, jumps twice,
looks with the mouse and fires two blasters whose cooldown, spread,
shot count and knockback are the kit's own resources; four flying
enemies that hover on a cosine, turn to face him and fire a
five-metre ray every quarter second; a ray test against spheres and
boxes in integers; a fall off the world that starts again. The
picture is seen from the eye:lib/scene3d.lovagained a
first-person camera, and the weapon is held where the kit's second
camera holds it, by the ratio of the two fields of view.tests/test_fps.pytransliteratesplayer.gd,enemy.gdand the
two weapon resources and runs them beside the port for 642 ticks of
a scripted play -- walking, looking, jumping the gap, emptying both
blasters into an enemy, taking fire, sliding along a wall, falling
off: the same position within four thousandths, the same yaw,
pitch, health, cooldown and enemies, tick for tick. On the native
runtime a tick is 2 ms and a frame 8 ms, and the SDL window holds
60 frames a second (apps/fps/README.mdhas the table); a run on
both runtimes draws the same picture to the byte.
python apps/fps/fps.py # WASD, space, mouse, E, left button python apps/fps/fps.py --shot out.png # one frame, no windowThe same rules, inside Godot.
native/lova-godotis the native
runtime as a Godot 4 extension class, andapps/godot/fpsis the
kit's own Godot project withplayer.gdandenemy.gdreplaced by
scripts that calllib/fps.lovaonce a physics tick and put the
answer into the kit's nodes. Godot draws its own scene -- the sky,
the models, the muzzle flashes, the impact sprites, the HUD -- and
LOVA decides everything that happens in it, in 0.6 ms a tick.
A seven-second recording (with the
sound), made bybuild.py --movie, shows the demo walk in, look
round and take three of the four enemies with both weapons; the
corner reads the rules' cost every tick.
cargo build --release --manifest-path native/lova-godot/Cargo.toml python apps/godot/fps/build.py path/to/Starter-Kit-FPS --run # play it python apps/godot/fps/build.py --movie=demo.mp4 # record the demoLogic runs right the first time. The word count, the games, the
log summary, the batch, the sandbox: every program's logic produced
the correct result at its first execution. Errors, when they came,
were caught at compile time with a repair hint, or reported at run
time as a structured anomaly, never as a crash or a traceback.Failure is data. The sandbox runs untrusted programs, one per
line, and reports each by hash and value or by the name of its
fault: an infinite loop meets itsbudget, a file read meets the
boundary it did not declare, text that is not a program is said to
be one. Nothing reaches the sandbox, and the sandbox needs no grant.Contracts are the program's own. The batch gives each job its
own budget and counts the jobs that exceeded it; the repairer states
aconservecontract and mutates the patient until it holds,
keeping only mutations that shrink the surprise. 219 of 300 jobs
finish under budget, exactly as an outside computation predicts;
three repair targets converge in 39, 37 and 20 attempts,
reproducibly.Provenance is queryable from inside. The evolved winner and
the repaired program each print their text, their generation, why
they exist and the length of their descent, with no help from
Python.The world is declared. Two processes exchange datagrams, a file
is read, the clock is consulted, each under a boundary that names
the kind of effect while the host names the places. A program that
did not declare an effect cannot reach it, and the compiler says so
before the run.Programs are integers. Every one of the programs, re-run from its
Stage-2 projection, gives the identical output and value, the
3 000-character game included.A model writes it from one page. A fresh Claude session given
corpus/language_card.mdand the 80 tasks of LOVABench v3, one
answer each and no execution, wrote 79 of 80 correct, exactly
its score in Python on the same tasks; the algorithmic category was
20 of 20 in both. The language costs a model nothing to write, and
gives its programs contracts, budgets and structured faults Python
does not have (journal/experiment_17.md).A model fixes it from the fault. In a loop where a fresh session
runs its code and reads what came back, ten tasks with loops, lists
and text: all ten correct in both languages, LOVA in eleven
submissions, Python in ten. The one LOVA miss came back as a compile
fault with the excerpt, the line, and the replacement to write; the
next submission passed. The LOVA answers ran as a function call
under a budget with nothing granted; the Python answers needed a
subprocess and a timeout (journal/experiment_18.md). On eight
bigger tasks with three sessions per language, every compile fault
a session met was fixed at its next submission, and the sessions
called the diagnostics "excellent"; a step budget now reports which
functions it went to (journal/experiment_19.md).It runs anywhere Python does, and fast where Rust does. The core
has no dependencies, so the same programs run under CPython and PyPy,
and the 1 104 tests pass on both; the native runtime runs the same
byte sequence at 10-12 million steps a second and inside Godot.Text is a value. A string literal is one node;
words,split,join,parse-intand the rest are one operator each; a word count
of 10 000 lines runs in 5.5 s on CPython where it took 28 (M25).A fault says where, and a fix is a patch. Every anomaly carries
the source span of the expression at fault and its text; the MCP
server'slova_patchreplaces that span -- or a text inside a named
def -- and checks the result. A failedexamplenames the single
edit that makes it pass, with the replacement. The loop an agent runs
is execute, patch, execute, and a fix costs the size of the fix.A program answers questions instead of being read.
lova_show
gives one def by name with its span and parameters,lova_scopewhat
is bound at a point,lova_callerswho calls whom -- so an agent
reads the def it asked about, not the file.What the programs found was fixed the same day. Writing them
surfaced four edges -- in input, in self-reference, in program ids,
in arguments -- and each became a compile-time check, a prelude
function or a command-line form before the day ended, with a test
for every shape. The journal keeps the record.
Where LOVA fits
Every language has a place. Python is the glue and the notebook, Rust
the systems layer, JavaScript the browser, Erlang the switch that never
goes down. LOVA's place is code that an AI writes, a machine runs, and
a person need not read: the small programs agents produce all day,
the rules and policies a system lets its users or its models change,
the routines a long-running service tunes by itself. What it gives that
place is a set of guarantees no general-purpose language carries.
Against other languages
| What a program gets | Python | Rust | Haskell | Clojure | Unison | LOVA |
|---|---|---|---|---|---|---|
| Faults as structured data, not text | – | partly | partly | – | – | yes |
| Ill-formed programs unrepresentable to a generator | – | – | – | – | – | yes |
| Effects declared by the program, granted by the host | – | – | typed | – | partly | yes |
| Termination guaranteed | – | – | – | – | – | yes |
| Cost contracts inside the program | – | – | – | – | – | yes |
| Programs as first-class data | – | – | – | yes | yes | yes |
| Provenance queryable from inside | – | – | – | – | partly | yes |
| A function as an evolving population | – | – | – | – | – | yes |
| Repair guided by the program's own deviation | – | – | – | – | – | yes |
| Zero dependencies, one core on CPython and PyPy | core | – | – | JVM | runtime | yes |
How LOVA does each, in the order of the table:
- Every fault carries a kind, a position path and a repair hint, at
compile time and at run time alike;when-anomalylets a program
catch its own and branch on the code. valid_nextgives the legal next tokens at every step, so a
generated program cannot be syntactically or scope-invalid.(boundary "fs-read" ...)declares the kind of effect,--allow
names the places; an undeclared effect is a compile error.- Step and depth ceilings are built in: a loop that never ends is a
structured anomaly, never a hang, and a run over budget names the
functions the steps went to. (budget n ...)per call, per job, per untrusted line; the program
catches its own overrun.quote,eval,read,explain,hash: a program is one
integer, and a value the language handles.why,generation,lineage-queryare operators; the record is in
the value, not in a side channel.defpop,evolve,select: the winner explains its descent.conservestates the contract,surprisemeasures the miss,mutateproposes; three targets repaired in 39, 37 and 20 attempts,
reproducibly.- The core is stdlib-only; 1 104 tests pass on both interpreters.
And the measurement behind the claim that it costs a model nothing: a
fresh Claude session given one page of LOVA wrote 79 of 80 benchmark
tasks correctly, single-shot, exactly its score in Python.
Three of these exist elsewhere, scattered: effects in types (Haskell,
Koka), code as data (Lisp, Unison), a system that heals itself
(Erlang). None of them has all three, and none has the other seven.
LOVA is the language where they meet, in 64 operators.
Scenarios
The agent's sandbox. An agent that works needs to compute
constantly -- a sum, a transform, a check -- and today it writes Python
into a container. In LOVA the program cannot hang, cannot touch a file
or the network it did not declare, and reports every failure as data.apps/sandbox.lova runs untrusted programs one per line, under a
budget, reporting each by digest and value or by fault name, and is
itself twelve lines of LOVA needing no grant. The MCP server (lova mcp) serves this to any host.
The rule layer of an application. Interface, storage and network
in the language you already use; the one piece that decides -- a
pricing rule, a policy, a user's or a model's script -- in LOVA, edited
live, run under a budget with no capability, and unable to hurt the
application that hosts it. apps/shell/policy_app.py is a Python web
shell whose only decision is a LOVA rule you can edit and break in the
browser; apps/tanks/tank_game.py is a tank battle whose every rule --
movement, bullets, the enemies' aim, the win -- is lib/tanks.lova,
called ten times a second from a Python window that owns nothing but
the pixels and the keys.
Generated code that must be auditable. A program is an integer
that carries its lineage: which model, when, from which parent, why.apps/repair.lova and apps/evolve.lova print the descent of the
program they produced. Where AI-written code has to be traced before it
ships, the record is in the value, not in a side channel.
Routines that tune themselves. A service's heuristics -- retry
policy, ranking weights, thresholds -- as a defpop population:
variants compete, losers retire, winners are cloned and mutated, and
every version can say why it exists. The contracts (conserve,budget) bound what evolution may do.
A target for constrained decoding. For a smaller or on-device
model that must emit code that compiles, valid_next is the grammar:
at every step, only the legal tokens are offered. The fine-tuning corpus
(corpus/finetune.py, 3 000 verified pairs) and the one-page language
card are ready.
What LOVA is not for: interfaces, graphics, real-time input, floating
point, or code a person will maintain by hand. Those are the trades it
made for the guarantees above.
Measurements
All numbers come from journal/; each links to a reproducible script inexperiments/. These are research-scale results, not benchmarks with
statistical guarantees — sample sizes are stated for each.
| Metric | Result | Source |
|---|---|---|
| pass@1, same tasks & same LLM | LOVA 60/60 vs Python 59/60 | Exp 07 (LOVABench v2, 60 tasks, single run) |
| test cases passed, same comparison | LOVA 180/180 vs Python 177/180 | Exp 07 |
| Raw byte density vs Python, number-theory tasks | 25.8× | Exp 07 (v1's 20-task slice reported 39.2×) |
| LLM-token density vs sympy-Python, number-theory tasks | 2.0× (50% fewer tokens) | Exp 11b (LOVABench v2, 60 tasks, tiktoken cl100k_base) |
| LLM-token density vs pure Python, number-theory tasks | 8.5× | Exp 11b |
| LLM-token density vs Python, algorithmic tasks — Stage 2 | 1.13× (denser) | Exp 14 |
| ...same tasks, Stage-1 s-expression surface | 0.66× — Stage 1 costs 1.5× MORE | Exp 12 |
| LLM-token density vs sympy-Python — Stage 2, LOVABench v2 | 5.38× | Exp 14 |
| Stage-2 surface losslessness | 2150 / 2150 round-trips exact | Exp 14 |
| Byte density vs Python, algorithmic tasks | 1.19× | Exp 12 |
| Tasks needing recursion/iteration that LOVA can express | 44/44 cases (0/10 before M9) | Exp 12 |
| Algorithmic density gap closed by operator spelling alone | 30%, for zero token slots | Exp 13 |
...by adding lt and sub as primitives |
9%, for 2 slots — so they shipped as macros instead | Exp 13 |
| ...residual, unreachable by any token-table change | 61% (s-expression syntax) | Exp 13 |
| Runaway programs producing a structured anomaly | 5/5, all with the full L2 schema | Exp 12 |
| Unbound references in generated programs | 248/1000 → 0/1000; runnable 29% → 38% | Exp 16 (scope-aware generation, M17 re-run) |
| Self-healing, written as a LOVA program | 9/10 seeds improve, 3/10 converge, best 35 → 1 | Exp 15 (10 seeds × 30 generations) |
| Constant-folding compression | 58.5% fewer nodes, 43.9% fewer bytes | Exp 08 |
| Telemetry-weighted vs uniform sampling | +32 pp pass-without-trap (88% vs 56%) | Exp 10 (N=50, re-run at M16 with scope-aware samplers) |
What the correctness number actually measures
The 60/60 is real and it is narrower than it looks. LOVABench's tasks
were authored in LOVA, and the v2 prompts state the formula outright
— "Compute p(tau(sigma(n)))". So what the Claude-as-oracle baseline
measures is transcription into s-expressions, not program synthesis.
Read it as evidence that the surface is writable by a model, which is
worth knowing, and not as evidence that a model can program in LOVA,
which it does not show. An algorithmic corpus (Q33) would measure that.
What the density numbers actually measure
Read the two density rows together, because they disagree and the
disagreement is the finding.
The 8.5× comes from number-theory tasks where the LOVA program is(sigma n) — a one-byte built-in — and the Python is an import plus a
sympy call. That comparison credits the language for its standard
library. It is a real and defensible argument for a domain-shaped
operator set, but it is not a measurement of writing programs.
Exp 12 measures ten tasks where neither side has a shortcut and both
have to write the algorithm out: factorial, fibonacci, primality,
Collatz, Euclid's gcd, and so on. There LOVA's Stage-1 surface costs
1.5× more LLM tokens than Python, and the Stage-2 projection does
not rescue it (0.65×) — (merge n -1) is seven tokens where n - 1
is three, and no tokenizer fixes an operator set that spends five AST
nodes on a decrement.
So: LOVA is dense where its built-ins match the task, and less dense
than Python for general algorithmic code. Both numbers stay in the
table.
Exp 13 then decomposed that gap and found the table was the wrong
instrument for it: 51% of the Stage-1 token cost is operator names and
25% is parentheses, so shortening the names closed 30% of the gap for
zero slots — three times what the two candidate new operators were
worth — and the remaining 61% is s-expression syntax that no allocation
of 64 slots can reach.
Exp 14 built the instrument that can reach it. The parentheses were
never necessary: the byte encoding has no delimiters, because arity
determines structure, so Stage 1 was spending a quarter of its tokens
re-stating what the substrate already knew. The Stage-2 surface is the
byte sequence written in characters —
Stage 1 (defn square [n] (mul n n))(square 7)
Stage 2 W0\1*LL$A7;
— and it takes algorithmic code from 0.66× to 1.13×, past the 0.76×
ceiling the token table could never beat, and LOVABench from 2.00× to
5.38× against sympy-Python. It round-trips losslessly 2150/2150.
So the honest one-line claim is not "8.5× denser". It is: LOVA's
Stage-2 surface is 5.4× denser than sympy-Python where its built-ins
match the task, and 1.1× denser where they do not. Smaller, and it
survives the obvious attack.
One thing this does not show: whether a model can write Stage 2.valid_next should make it easier than Stage 1 — there are no
delimiters to misplace — but that is untested and is the project's
load-bearing open question (Q47).
Note on honesty: Exp 11's first run on the narrower 20-task set reported
2.5×/13.3×; re-running on the broader 60-task v2 set dropped it to
2.0×/8.5×. The v2 number is the one quoted above. NULL, weakened and —
as of Exp 12 — outright negative results are kept in the journal on
purpose.
Repository layout
core/ reference implementation (tokens, types, runtime,
conservation, lineage, populations, compiler, telemetry)
spec/ design documents — axioms, token table, paradigm inheritance
corpus/ LOVABench v3 (80 tasks), evaluator, fine-tuning corpus + language card
experiments/ numbered, reproducible validation scripts
journal/ research log — one entry per experiment, NULLs included
apps/ first-class LOVA programs
lib/ prelude.lova — the standard library, written in LOVA
tests/ 1 104 unit tests, stdlib only
native/ the Rust runtime (lova-rt) and its Godot extension (lova-godot)
What LOVA still cannot do
Stated plainly, because the list is short and the omissions are large:
- It is not a data language. The native VM does 10-12 million
steps a second and a game's tick in under a millisecond; a word
count of tens of thousands of lines is seconds. Millions of lines,
or arithmetic that wants a vector unit, are not this language yet
(Q76). - IO is whole values.
fs-readreads a whole file,net-recvone
datagram: there are no handles and no streams (Q72). The terminal is
ambient rather than declared (Q68). - The core table is full, and the language grows past it. 63 core
operators andEND; the text family (0x40-0x4F, M25, full at M32)
was the first addition beyond 64, and the next
operator has to displace one of the number-theory family (Q74). - Modules are textual.
(use "name")includeslib/name.lova
once and transitively, anddrop-unusedmakes it free — but two
libraries defining the same name shadow in inclusion order; there
are no namespaces (Q50 closed at that limit). - A population is its own value, not a list of programs. That
sidestepped parameterised lists (Q42) for now;List<T>remains the
better long-term shape (Q63). headis checked at run time. A cons cell holds any value —
trees and lists of programs are representable since M17 — sohead's
result type follows its list, which the checker cannot see. A
parameterisedList<T>would recover the static answer (Q63).- Parameters are untyped. The checker infers a function's shape
— arity and return type — from its lambda (M20), so a partial
application or a call result in the wrong slot is a compile error;
but LOVA has no parameter annotations, so a parameter misused inside
a body is caught where its value is used, at run time (Q43). The
generator still works at theFnlevel (Q71). - Generation cannot reach mutual recursion. Since M16 the
generation state machine keeps scope, so an unbound or wrongly typed
reference is unrepresentable in a generated program (Exp 16: 704/1000
→ 0). But a left-to-right machine cannot name something bound later,
so a mutually recursivedefchain — legal since M12 — compiles and
cannot be generated (Q64).
Reading order
spec/axioms.md— the 10 design invariants and the argument for eachspec/paradigm-inheritance.md— the seven PL trajectories LOVA synthesisesspec/tokens.md— the 64-operator tablejournal/README.md— the experiment logCLAUDE.md— full project orientation (written for an AI session)
Lineage
LOVA inherits its architectural vocabulary — PFS, conservation, lineage,
surprise, evolution, Δ-security — from DNA OS v3, a separate
(unpublished) research project by the same author. The concepts are
shared; the code here is an independent reimplementation, not a fork.
Design philosophy
Human readability is an explicit non-goal of the substrate. The
Stage-1 text surface exists to bootstrap the project and to audit
programs on demand — it is tooling, not the language. Contributions
that make LOVA nicer for humans at the cost of Stage-3's pure-integer
representation will be rejected on principle (see Axiom 10).
There is also no PnL / reward objective anywhere in the language. Users
declare their own objectives through conservation contracts and surprise
budgets; the substrate only enforces compliance.
License
MIT — see LICENSE.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found