Aug 30, 2026 By Colin Moffat

Why Python is the best language for AI-written code

I spend most of my working life with AI coding agents these days, across a bunch of languages and a bunch of very different projects, and one question has been quietly nagging me the whole time: how much does the language actually matter? I know roughly how these models get made, and knowing that is exactly what planted the suspicion. It seemed likely to me that a model would be stronger in some languages for some kinds of work, and that if that was real, the reason would be simple: it comes down to how much code the model has watched doing that kind of task in that particular language.

Two pieces of background explain the suspicion, if this isn’t your daily world. First, how these things learn: coding models are trained on enormous piles of public code, much of it scraped from places like GitHub, and they get good at things roughly in proportion to how often they’ve seen them. Nobody hand-writes rules about how a web server should look; the model absorbs a few hundred thousand web servers and develops an opinion.

Second: programming languages have day jobs. In principle any language can do anything, but in practice ecosystems snowball. One good library attracts users, users write tutorials and more libraries, and a decade later the language has a reputation and a gravitational pull. Python ended up doing the world’s data science and machine learning, plus a long tail of scripts and glue. TypeScript and JavaScript run the web, overwhelmingly. Go built itself a home in cloud tooling and infrastructure. Ruby, these days, mostly means Rails web apps. So the pile of code a model learns from isn’t just big. It’s lopsided, and lopsided in a different direction for every language.

Put those two things together and you get a really tempting intuition. Here’s the concrete version of it I’d have bet money on: TypeScript should be better at building web apps than Python, because nearly all of TypeScript’s corpus (the body of public code a model learns from) is web applications, while Python’s is scattered across half of software. More relevant examples in training, better output at the keyboard. Right?

I wanted to know if that intuition was actually true. So I designed a study to test it, and had Claude Code help me make it happen: first measure what each language’s public code really contains, then hand an agent identical work in four languages and watch what happens.

What public code is actually made of

For the measuring step, I used The Stack v2, the deduplicated public-code dataset used to train StarCoder2 and about as close as you can get to “what a code model actually saw,” and classified 3,000 sampled repositories by what they depend on and what they say about themselves. Django means web backend. Pandas and Airflow mean data. Cobra means CLI tool.

What each language's public code is actually made ofshare of bytes by category · The Stack v2, 3,000 sampled repositories
web 13.6%data/ML 22.2%tools 13.6%library 18.3%unknown 17.5%web 77%tools 27.5%infra 15.9%library 32.4%web 31.9%library 39.4%PythonTypeScriptGoRuby0%25%50%75%100%

(Rows don’t add to 100: the remainder is code that defied categorization.)

See the numbers
web data/ML tools infra apps library
Python 14% 22% 14% 7% 8% 18%
TypeScript 77% 0% 2% 1% 9% 8%
Go 11% 2% 28% 16% 1% 32%
Ruby 32% 1% 9% 13% 2% 39%

The corpus had surprises in it before I ran a single test. TypeScript is 77% web and rounds to zero percent machine learning. Data science is essentially a Python monopoly; the amount happening in other languages is statistical dust. And Go, famously the backend language, is actually a corpus of libraries and command-line tools. The backend-services reputation is something people say about Go, not something people mostly do with it.

The experiment

Then the test. Twelve programming challenges, two each across six categories: web, data/ML, CLI tools, infrastructure, libraries, and a control group of pure algorithm puzzles, LeetCode-medium-to-hard type stuff, with no ecosystem attached at all. The control matters: if a language is just better at everything, it shows up there, and you can subtract it out.

Each challenge is a plain-English spec with a hidden test suite, written before any solution existed, that pokes the finished program strictly from the outside: a shell command, an HTTP endpoint, a TCP socket. Identical tests for every language, 401 in total. I handed each spec to a coding agent (Claude Code, headless) four times over: Python, TypeScript, Go, Ruby. Three repetitions apiece, isolated workspaces, no web access. 144 runs, about two and a quarter hours, $49.52, five and a half million tokens. I pre-registered ten predictions beforehand so I couldn’t quietly move the goalposts. Three survived.

The first result flattened my plan: the agent just did all of it. 136 of 144 runs passed every hidden test; the worst run in the study scored 97%. You can’t rank things that are all tied, and it wasn’t that the challenges were easy. One was a churn-prediction model graded on ROC-AUC, calibrated so a basic logistic regression fails the top tier. Every language cleared the top tier every time. The agent did feature engineering in Go. In Ruby. Unprompted.

So before anything else, one finding stands on its own: at this size of task, language choice did not determine whether the agent succeeded. And sit with that for a second, because it’s quietly the best news in the study: these models are just good now. They rarely got stuck, they shipped working software in every language I tried, and the code held up against tests written specifically to catch them out. More good software, built more easily, by more people. That’s the floor this data establishes, before we argue about anything else.

What did vary, reliably and repeatably, was the bill. I normalized every run against the average for that specific challenge, so task difficulty cancels out and 1.00 means “the average language on this task”:

What identical work cost, by languagetoken cost normalized per challenge · 95% bootstrap CI · n=36 runs each
1.00 = average language on this task0.880.951.071.09PythonRubyGoTypeScript0.800.901.001.101.20relative cost (tokens, per identical task)
See the numbers
language relative cost turns per run lines written
Python 0.88 14.1 215
Ruby 0.95 15.1 210
Go 1.07 16.1 388
TypeScript 1.09 23.2 285

Identical work cost about 24% more in TypeScript than in Python, and the gap is statistically solid. TypeScript needed 64% more back-and-forth turns to reach the same finish line. Go wrote nearly double Python’s lines for the same behaviour, in every category.

To be clear about what that table does and doesn’t say: the expensive languages did not produce worse code. Everything passed the same tests, and a code-quality rubric scored all four within a whisker of each other. The difference isn’t what came out. It’s how much work it took to get there.

Why? Not the reason I bet on

I had three candidate explanations, and the data killed the two I liked.

Three explanations, one pair of axesy is always relative cost · only the x-axis changes
1 · corpus share All 20 language × task cells: no pattern (ρ −0.10). Only TypeScript tracks its own corpus (ρ −0.90).
0.801.001.20rel. cost0%25%50%75%corpus share
2 · popularity GitHub rank vs cost: the most popular language is the most expensive.
0.801.001.20rel. cost#1#2#3#4popularity (1 = most popular)PyTSRbGo
3 · verbosity Lines per run vs cost: a clean upward slope (ρ +0.60). The boring answer survived.
0.801.001.20rel. cost200300400mean lines of codeTSRbPyGo

My original theory, corpus match, failed almost completely. Correlating each language’s corpus share against its cost across all twenty language-task cells gives −0.10, which is nothing. Worse, the details point the wrong way: Python’s cheapest categories were infrastructure and web, two of its smallest corpus slices. Whatever makes Python cheap, it is not “Python has seen more of this.”

Popularity failed too, and backwards in a way I enjoy: TypeScript just became the #1 language on GitHub by monthly contributors, and it’s the most expensive language in my study. Ruby, which every industry survey politely describes as declining, came second cheapest.

What survived is the boring answer: verbosity. The correlation between how many lines a language needs and what a run costs is +0.60 across languages, +0.58 across all 144 individual runs. Look at the shape of the cost table again: the two terse, say-what-you-mean languages first and second, the two strict, structured, ceremony-heavy languages third and fourth, on every effort metric I collected.

Part of that is mechanical: more code is more tokens. But why does Go take 388 lines where Ruby takes 210? That’s not the model’s choice. That’s the language. Explicit error handling on every call, no comprehensions, no shortcuts. TypeScript’s types, interfaces, and config are the same bet. That ceremony exists, honourably, to make large codebases legible to large teams. Real benefits, paid for in keystrokes. When an agent does the typing, keystrokes are tokens, and tokens are the bill.

Which collides with the industry story. GitHub, in the same report that crowned TypeScript, credits its rise partly to typed languages being better for AI coding, because the compiler catches the agent’s mistakes. Maybe, at scale. But at this task size I couldn’t detect that benefit anywhere: correctness was maxed out in all four languages, types or no types, while the cost of the structure showed up on every single run. The safety rail did nothing measurable; the toll booth charged anyway.

One thread of my original theory did survive, though, and it’s the useful one. TypeScript, the language with the most lopsided corpus, followed the corpus script faithfully: cheapest on web, its 77% category, and most expensive on data/ML, its 0% category and the single priciest cell in the entire study. Correlate TypeScript’s own costs against TypeScript’s own corpus and you get −0.90, about as clean as this kind of data gets. So my theory wasn’t wrong so much as it only applies at the extremes. It’s a threshold, not a dial: once a language has enough public code doing a kind of work, more doesn’t help. What hurts is having approximately none. Python clears the threshold everywhere, so nothing is ever foreign to it. TypeScript falls off a cliff in the one place its ecosystem has simply never gone.

That’s also the honest version of why Python does well, and it’s not the version I used to tell. It isn’t “huge diverse ecosystem makes the model smarter.” It’s two much less glamorous things stacked: no blind spots, and very few lines. Coverage without ceremony.

expression evaluator · performance test · expected vs emitted output, three TypeScript runs
rep 1rep 1: byte-identical to expected output for 65,525 chars, then nothing (966,704 chars missing)rep 2rep 2: byte-identical to expected output for 65,525 chars, then nothing (966,704 chars missing)rep 3rep 3: byte-identical to expected output for 65,525 chars, then nothing (966,704 chars missing)966,704 chars never arrived (93.7%)output stops at 65,525 chars = 64 KBall three runs, identical0expected: 1,032,229 chars

So, is Python the best language for your AI projects?

The answer this study earned is: it depends, but it’s likely a good choice. Here’s the whole decision, compressed.

The models are good, and that swamps everything else. They shipped working, verified software in every language, on every kind of task, almost every time. Which means the language that matters most is yours: you’re the one reading what the agent writes, steering it, catching what the tests don’t. Comfort beats every number in this post.

If you don’t have a comfort zone, because coding was never your thing until an agent made it possible (what people now call vibe coding, and I mean that in its honest sense: you describe, it builds, you steer), then yes: Python. It was cheapest overall, never worst at anything, and it’s the one language with no blind spots, from web servers to machine learning (which, remember, barely exists outside it). You will never be the first person solving your problem in Python, and when an agent is doing the writing, that’s exactly the road you want: paved, lit, and going everywhere.

And when something concrete pushes you elsewhere, let it. A web shop living in TypeScript should stay: web is its home turf and it’s perfectly competitive there. Just don’t drag it off-turf (“we’re a TS shop, just do the ML pipeline in TS” bought the worst cell in my entire study). If the running software matters more than the writing of it, Go is still a fine choice: the agent built production-shaped concurrency daemons in it without breaking a sweat, the ~20% token premium is paid once, and Go’s runtime advantages recur every day the thing runs. Because a language is always more than how efficiently an agent emits it: runtime, memory, deploys, teams, hiring. My study measured one line on the invoice. It’s a real line. It’s not the whole invoice.

Two things I’d do differently, and one I want to do next. I calibrated challenge difficulty against reference solutions I wrote myself, but the agent is a much better programmer than my “naive baseline,” and one throwaway run against the real thing would have shown me the ceiling in an hour. Well-specified few-hundred-line programs are, as of now, simply solved; any benchmark that hasn’t noticed is measuring nothing. And the experiment I want to run next is multi-stage projects: build, extend, extend again, the same codebase growing across sessions. All of Go and TypeScript’s ceremony is a bet on exactly that scenario, and my single-shot tasks never let the bet pay out. Maybe at stage four Python’s flexibility starts generating the mess that Go’s rigidity prevents, and the cost ranking flips. I genuinely don’t know, which is exactly why it’s the next thing worth measuring.


One model (Claude Sonnet), one machine, one point in time. These numbers will drift as models change, though I’d bet on the ceremony effect outliving any particular model version.

If you want the full methodology (the corpus pipeline, the challenge specs, the statistics, the pre-registered predictions and how few survived) the complete study write-up is here: Language × Task Affinity. It’s written for people who want to check my work rather than take my word for it.

All posts