About a year ago, it was common to read an argument which went something like this:
- LLMs can learn things from their training data
- This includes how to write software code
- They seem to be better at writing in languages which are present in the training data, and worse in rare or novel languages
- People will prefer to use LLMs for things that LLMs are good at
- Therefore, LLMs will be used to write code in languages heavily represented in the training data
- Which creates a feedback loop in which today’s most popular languages are reproduced more quickly, giving them ever greater weight in the training data
In other words, “JavaScript forever”.
But this doesn’t seem to match my own observations. Instead of cementing the dominance of existing languages, LLMs seem to be making it easier to adopt alternatives.
Why is this? Partly it’s because the feedback loop described above is incorrect, or at least incomplete. And partly it’s because there are other factors which pull in opposing directions.
Coding generalises
It turns out that although programming languages have differences from each other, they also share a lot: in the grand scheme of all written culture, JavaScript is not very different from C++ or even Haskell, Prolog, or Forth. If you can understand (by which I mean: recognise and reproduce) one, you’re pretty close to being able to understand the others.
Back in 2023 I wrote LLMs are hustlers, which makes the fairly obvious point that LLMs can handle much greater variety than traditional software. They are good at identifying patterns, and increasingly good at emitting patterned outputs too. Whereas a JavaScript interpreter and a C++ compiler are categorically different things, the act of writing code in either language is similar enough that LLMs which can do one can almost certainly do the other. Training in the specific idioms and use-cases of a language still help to increase quality, but the delta is much smaller than it first appears.
“Bouncing off the guardrails” works
Most code LLMs write has at least some errors (the same is true of code humans write: we spend a lot of time editing our code to remove the errors). LLMs are also pretty good at fixing errors, and this works especially well with languages which give good feedback in the form of error messages. Type-checks, unit tests, lints — all help to guide the LLM toward something that works. This raises the reward to having well-specified types, good tests, formal specifications, or just detailed documentation of intended behaviour that can be used to create tests.
This should not be totally surprising. Perfect knowledge of the language or standard library APIs is not required, even for the best human coders. Competence is a relationship between the coder and the environment, and the reason most programming languages provide parsers with good error messages, Language Servers, linters, and other tools is that their use is an essential part of the practice. Writing code that compiles (and works!) at the first attempt is a really good feeling, but it’s rare for humans and for LLMs. The guardrails matter!
For LLMs, in-context knowledge is a reasonable substitute for training — this is why prompting works at all. A language with good error messages can steer an LLM toward a successful result even if it has no training-era familiarity with the language at all. I’m fairly sure Podlang does not feature heavily in the training data, but we gave it good enough error messages that LLMs are able to use it astonishingly well.
Porting is faster now
“Rewrite it in Rust” was already a meme before LLMs came along, but the ability to automate parts of the process has sped things up. If a piece of software has good specifications or tests, porting it from one language to another can now be done mostly autonomously by agentic coding tools. The process isn’t perfect, but it’s effective enough. This cuts against the inertia of the past: if we invent a new, better language then LLMs can help us to port our software to it much more quickly than would otherwise have been the case.
Programmers are neophilic
Programmers love new things, and LLMs allow them to make new things more quickly, including new languages. It’s true that many of these projects will fail, but it’s easier than ever to make your own programming language. It might not be easier to design a good language, but in any case where implementation was the bottleneck (or even where the prospective language designer thought it was a bottleneck and now does not) then the odds of the language being released to the wider world have gone up.
This works particularly well for DSLs, where the effort of maintaining a small parser, interpreter, and toolchain is just high enough to out-weigh the benefits of a language that targets your exact use-case. There’s even a virtuous circle here: give an LLM a domain-specific language, and you guide it towards producing software which expresses exactly (and only!) the concepts you want.
LLMs are individually slow to learn, but incredibly fast to scale that learning
Training an LLM with 2026-era technology is slow and expensive. Truly absurd amounts of GPU-time are required. But once the model knows something, every instance of the model knows that thing. In the past, the battle to get a new language adopted was limited by the number of humans who knew that language. Adopting the language was risky, because your existing programmers may not be proficient in it, and new hires would likely require extra training. The social network of people who know the language is sufficiently sparse that the knowledge of how to use it effectively may fail to be transmitted at all, leading to the craft dying out entirely.
However, once the rudiments of the language are in the LLM’s training data, or included in synthetic RLVR environments, baseline competence is available cheaply. My own experience is that this speeds up human learning too: if I want to learn an esoteric language, Claude can teach me reasonably well, and I’m no longer at risk of being left without anyone who knows how the language works.
There are probably more factors at work, but all of the above point in the direction of greater diversity of programming languages, not — as was being assumed — a monoculture.