I started working on Elo with three objectives in mind:
- Build a simple & clean expression language to embed in Klaro Cards.
- Train myself and get an opinion about the new AI-driven coding wave, testing Claude Code in particular.
- Keep working on my long-standing personal research towards a data-friendly programming language. See here, here or here.
7 days, 110 spec-driven iterations.
That’s what it took to write the compiler, documentation, website, and test suite.
Claude Code and I
I wrote all the prompts, but not a single line of code. Claude co-designed the language with me and wrote everything. I’m mind-blown.
Not because the task was impossible—it wasn’t. Except maybe for runtime data schemas taken from Finitio, there’s a feeling of déjà-vu here. The language is pretty simple, does not have a decent static type system and type inference algorithm yet. It looks like a student coding project.
But I changed my mind very often, requiring several refactoring passes. Claude never got stuck and I didn’t have to jump into the code to help. What was still science fiction 3 years ago is a reality in 2026.
How do we know it’s correct?
Sceptics will (rightfully) ask: How do we know the compiler is correct?
It’s the only question that matters. And the answer is: we don’t know yet.
- I haven’t looked much at the source code, even if the architecture is pretty clear to me.
- I haven’t even formally reviewed the tests.
So the truth is: Elo’s compiler could very well be super buggy. That’s why it’s a version 0.9.x and not a 1.0. I will certainly make a more serious review & testing pass when integrating it into Klaro Cards early 2026.
Why the confidence?
Why am I confident releasing Elo, then?
Because the test method was serious. It’s the main reason why this project never derailed in my opinion. And it’s the only way I see AI-driven development succeeding in the future.
If you look at the git history, you’ll see that the very first thing I did was to ensure we have unit, integration and acceptance tests, with a very clear contract:
- Unit tests check that basic blocks work fine. That the parser emits the right abstract syntax tree, for instance.
- Integration tests check that we get the expected compilation from a given
.eloprogram. - Last but certainly not least, acceptance tests run compiled programs with
ruby,nodeandpostgresql; all of them areassert(...)calls in Elo.
(In fact, integration tests are not even necessary. We had to rewrite all expectations all the time anyway, as we changed our mind on the compilation patterns. Acceptance tests are key, in comparison).
That offers no strong guarantee of course, but if you look at a few acceptance tests and the way they are executed, and if you agree with what you see, then you know things could not be completely wrong.
The devil is in the details though, and I do expect some surprises in the future. Nothing too bad, I guess.
What’s next?
Well, Elo certainly deserves static type checking, but I’ll have to refresh my memory to guide Claude Code here.
If you know me, you probably guess that I’ll add relational algebra to Elo. It’s very much underway: Claude Code completed Bmg.js in 2 hours this morning, porting almost all operators from Bmg ruby.
Guess what? The methodology was the same: if a relational operator provides the expected relation output on known input relation(s), and if that’s true even on various edge cases, then the implementation is probably correct.
Blackbox software engineering with strong input/output assertions is the future of software engineering, really. We need data-friendly programming languages for that, though.
Enjoy Elo, give your feedback on github, don’t forget to support this work.
Interested in my Claude Code setup?
-
Have a look at our safe-setup to run Claude in dangerous mode in a docker container.
-
Look at CLAUDE.md and a few subagents I wrote to help me in certain tasks. I underused them though.
I’m still new to all those things too, so if you have any advice, please share it on github (or privately of course).