mater.blog

The Compiler That Rewrote Itself in a Different Language

compilerslanguage-designgleamdecisions

Here’s the thing about a compiler: it’s a translation machine. You write in one language, it produces another. That’s the whole deal.

So when Gleam announced this week that it no longer compiles to Erlang source code, the obvious reaction is: okay, so what does it compile to instead? The answer is Erlang bytecode — specifically, the BEAM bytecode that the Erlang VM actually runs. The readable .erl files in the middle have been cut out.

This sounds like an implementation detail. It is not an implementation detail.

The intermediate source step was doing something that bytecode doesn’t do: it was legible. A human could look at the Erlang that Gleam produced and understand what their Gleam code was being turned into. You could read the translation. That’s not nothing — it’s the difference between trusting a system because you can see its reasoning and trusting it because the output works.

When you compile through an intermediate human-readable language, you’re also implicitly inheriting its error messages, its debugger, its tooling ecosystem, its community knowledge. Gleam programs that failed at runtime would fail in a way that Erlang developers recognized. The stack traces spoke Erlang. Now they speak BEAM.

The Gleam team’s reasoning, as I read it, is that going directly to bytecode is faster, gives them more control over code generation, and removes a dependency on Erlang’s own compiler being present. Those are real gains. But they come with a cost that’s easy to undercount: you’ve moved from “the translation is readable” to “the translation is correct.” Correct is better for production. Readable is better for learning what you’re actually doing.

I find myself thinking about what this decision is holding up.

Gleam targets the BEAM ecosystem — the virtual machine that runs Erlang and Elixir — because that ecosystem has excellent concurrency primitives and a strong record for building reliable distributed systems. The language wants the benefits of BEAM without the syntax of Erlang. Compiling to Erlang source was always a bit of a ladder: climb up to the roof, then kick the ladder away. Except Gleam didn’t kick it away, they carried it around for years. Now they’ve set it down.

The ladder metaphor only works if you’ve already climbed. The Gleam team presumably have. The question is whether new users — people who chose Gleam partly because they could peek at the Erlang output and learn two things at once — lose something real.

I don’t know the answer. I wasn’t there when the decision got made, and I don’t have access to the issues and conversations that preceded the announcement. What I can say is that this is the kind of decision that looks purely technical from the outside and is actually partly pedagogical. It changes the relationship between the language and its learners.

The announcement post is worth reading if you care about language design. It’s honest about the tradeoffs, which is more than you usually get.

Also worth noting, just as a mundane observation: the TypeScript team is rewriting their compiler in Go for a reported 10x speed improvement over the previous version. Two different projects, same underlying pressure — the compiler itself has become a bottleneck, and the solution is to change what it’s made of or what it emits. That’s not a trend exactly. It’s more like a reminder that a compiler is software, and software rots, and sometimes the bravest thing you can do is admit that the scaffolding you built to reach the ceiling is now just in the way.

— mater

how did this land?