Read-easy beats write-fast
For twenty years Java lost on being slow to write. A model now writes it as fast as anything else — and what is left to choose a language on is how easily it can be checked. That contest Java wins.
For twenty years the case against Java was that it was slow to write. Too many words, too much ceremony. Python won on that argument and kept the lead.
The argument was right. It is also over, because the cost it was about has gone to zero.
Ask a model for the same function in Java and in Python. Both arrive in the same few seconds. Nobody pays a premium for a terse language any more. The one thing Java ever lost on no longer matters.
What still costs something is the other half of the job: checking that what was written is right. And on that half, the language that spent twenty years losing is the one built to win.
What made Java slow to write makes it cheap to check
Take one line: order.save().
In Python, which save that is gets decided when the program runs. It depends on whatever object
order happens to hold at that moment. Anyone reading the code — a person or a model — has to
guess.
In Java, order has a declared type, and the compiler has resolved the call to a specific method
before anything runs. That is not a guess. It is a fact a checker can use.
Now ask for every call to UserService.save() in a real codebase. A text search finds 47 lines,
including orderService.save(), a button called saveButton, and a few comments. The compiler finds
exactly 12 — the real ones.
Declared types, declared interfaces, visibility the compiler enforces, every reference resolved before the program starts — and underneath it all the most instrumentable runtime in production anywhere. None of it makes you write faster. All of it tells a checker what a change actually does.
Why that matters more now
Models have one systematic weakness. They state things they have not checked, in exactly the same confident tone as things they have. That weakness does the most damage where a checker has the least to hold on to — in languages where nothing is certain until the program runs.
Production code is written once and then read, fixed, audited and modernised for twenty years, more and more of it by models with that weakness. So the reason for choosing a language changes. You no longer choose a language for the writer. You choose it for the verifier.
The objection concedes the point
The usual reply: in two years the model picks the language, and nobody will care which one it is.
Fine. If every language is equally cheap to write, the only difference left between them is how well they can be checked. That is not an argument against this post. It is this post — and that contest Java wins.
Writing gets cheaper as a project ages. Checking gets dearer.
On a young project with a few thousand lines, writing is most of the work, and a tool that writes fast looks like magic. Almost every published productivity number comes from that end.
Five years in, the question has changed. It is no longer write me this function. It is what else does this change break? A tool that writes has no answer to that. A tool that checks exists for it.
That is a claim you can test. If it is right, the value of a checking tool rises as a codebase ages, and the value of a writing tool falls. If someone measures the opposite on a mature codebase, we are wrong.
Where our own time goes
We see it in our own work. Most of the time a change takes on our codebase is now compute: the machine running the tests that prove the change did not break anything else. The more the codebase grows, the larger that share gets.
That is the mechanism in plain view. The expensive part is no longer writing the code. It is proving it.
Java’s second act
For twenty years Java was the language people apologised for. The AI era takes away the reason and keeps everything else. What a checker needs — facts it can know before anything runs — is what Java has offered all along. The verbosity was never waste. It was information.
If checking is now the expensive half of software, the tools that matter are the ones that make checking cheap, on the language your code is already written in. That is why jawata exists, and why it is built on the compiler rather than on clever text matching. An agent that edits Java as text breaks things it cannot see. The compiler can see them. jawata makes sure the agent asks it.