For months now, I have been telling our teams something that would have sounded irresponsible not long ago:
I no longer care very much which programming language we choose.
Java, Python, Go, C#, pick one. Unless there is a hard operational reason, the choice matters less than it used to. The LLM writes a growing part of the implementation anyway. Syntax is still there, compilers are still there, runtimes are still there, but the center of gravity has already started to move.
This does not mean programming languages are dead.
It means they are no longer the main battleground.
What comes next, in my opinion, is more radical. The next important programming language may not be written for us at all. It may be built for machines.
That idea bothers people for good reasons.
We have spent decades treating code as something humans must read, review, debug, and maintain directly. Readability became a virtue not only because it is elegant, but because it is practical. Teams survive on shared understanding. Software survives on the ability to inspect what it does.
That assumption is now under pressure.
If a model can reliably generate implementation from intent, then the human-readable syntax starts to look less like the essence of programming and more like a compatibility layer. It is still useful. It is still necessary today. But it may not be where the deepest optimization happens tomorrow.
We have seen this pattern before.
RISC stripped processors down to what compilers could reason about more cleanly. Humans do not sit around reading RISC assembly for pleasure. That was never the point. The system improved because the representation became friendlier to the machine process that mattered.
APL did something similar in another direction. It compressed thought into a notation so dense that most developers rejected it immediately. Lisp and Prolog also arrived carrying abstractions that were, in many ways, ahead of the infrastructure around them. These ideas did not fail because they were foolish. Many of them failed because the ecosystem, tooling, and habits of the time were not ready to support them.
Now we are entering a period where the reasoning infrastructure is no longer missing.
That changes the question.
The old question was: which language helps humans express software best?
The next question may be: which representation helps machines reason, generate, transform, and validate software best?
That is not the same thing.
Human language is full of ambiguity, context leakage, approximation, and shortcuts. Even our programming languages, for all their precision, are still shaped by human cognitive limits. They are written to be inspected by us, discussed by us, and taught by us. They carry history, style, ergonomics, and culture.
Machines do not need most of that.
If a model could operate in an internal representation designed around its own architecture rather than ours, what would that representation look like? Would it be sequential the way our code is sequential? Would it be token-heavy? Would it resemble syntax at all? Or would it look more like a graph of constraints, behaviors, proofs, transformations, and execution paths?
I suspect it will be closer to the latter.
And if that happens, we will have to admit something uncomfortable: the artifact that matters most may become unreadable in principle, not merely unreadable by convention.
That distinction matters.
Unreadable by convention means a human can still dig through it if necessary, though perhaps with pain. Generated assembly, minified JavaScript, heavily optimized compiler output, these are unpleasant, but still fundamentally open to inspection.
Unreadable in principle is different. It means the machine-native form is not a thing humans can meaningfully reason through line by line because it was never meant for our minds in the first place.
At that point, “just read the code” stops being a serious answer.
This is where many people instinctively panic, and not without reason.
The first objection is interpretability.
If machines generate software in representations we do not directly understand, how do we trust it? How do we debug it? How do we certify it? How do we govern it? How do we hold anyone accountable when something fails?
These are valid questions.
But I think we sometimes ask them as if opacity were new. It is not new. We already live on top of layers we do not fully inspect. Very few people understand the transistor-level behavior of the processors they use. Very few inspect compiler internals, kernel schedulers, distributed storage engines, cryptographic implementations, or neural network weights directly.
We already work through abstractions, trust boundaries, and verification practices. We already accept that much of engineering is about proving behavior, not about personally reading every layer.
The difference now is one of degree, and that degree is large enough to become a category shift.
The compiler analogy starts to break down because the compiler still transforms from a human-authored source we consider primary. In the future I am describing, the human-authored source may be only a specification, a set of constraints, or a behavioral contract. The generated artifact may be the primary executable reality, while the human-facing expression becomes merely the governance layer.
That is a real shift.
If this happens, then software engineering moves upward.
Less syntax.
More semantics.
Less hand-written control flow.
More specification.
Less emphasis on reading implementation.
More emphasis on verifying behavior.
This is the part that interests me most.
The future of engineering, in that world, is not about surrendering to black boxes. It is about building a stronger verification stack around artifacts we no longer expect to understand the old way.
That stack is not mysterious. We already know many of its ingredients.
Property-based testing.
Formal specifications.
Behavioral contracts.
Type systems with real meaning.
Differential testing against reference implementations.
Sandboxed execution.
Trace validation.
Constraint checking.
Model checking where it is practical.
Runtime monitoring where proof is too expensive.
The probabilistic nature of LLM-driven systems is real. It is not small. But that does not make it mystical. It makes it an engineering problem.
When people say, “If we cannot read it, we cannot trust it,” what they often mean is, “We no longer have our old trust method.”
That is fair.
But the answer is not to freeze progress until machine reasoning stays comfortably human-shaped. The answer is to invent better trust methods.
This is also why I have stopped caring so much about language choice in ordinary delivery work.
Teams still debate languages as if the main problem were syntactic efficiency or developer taste. Sometimes it is. Often it is not. More and more, the real questions are elsewhere:
What is the specification?
What are the invariants?
What are the trust boundaries?
What does failure look like?
What must be proven before this system is allowed near production?
What is the observable behavior we care about?
These questions are not secondary anymore. They are becoming the work.
When an LLM can produce ten plausible implementations before lunch, implementation itself becomes cheaper. Cheap things lose strategic value. The scarce thing becomes judgment.
Not style judgment.
System judgment.
You still need taste, but now it is taste about boundaries, constraints, semantics, and verification, not only about elegant code structure.
That is a different profession, or at least a profession shifting under our feet.
There is another layer to this.
We often talk about AI as if it will replace programmers by making them unnecessary. I do not think that is the right way to frame it.
What is more likely is a redistribution of effort.
Less time spent spelling out the obvious.
More time spent deciding what must be true.
Less time spent writing repetitive plumbing.
More time spent defining interfaces between intent, behavior, and evidence.
The programmer does not disappear. The role hardens around the parts that still require responsibility.
And responsibility is the key word.
A machine can generate an implementation. It cannot carry accountability for what that implementation does in the world. It cannot own the consequences of a brittle assumption, a security failure, a broken workflow, or a silent misclassification in production.
We do.
That is why specification and verification are not clerical layers around the real work. They become the real work because they are the points where responsibility can still be exercised consciously.
This is also why I do not buy the lazy version of the argument that says everything will become a black box and we will just have to accept it.
No.
We will accept opacity only where we have built a discipline of evidence strong enough to stand in place of direct readability. If we do not build that discipline, then we are not doing engineering. We are doing faith-based deployment.
And that has never ended well.
There will be resistance to this shift.
Some of it will come from people who are attached to the craft in its current form. I understand that. There is beauty in readable code, in a well-shaped function, in a clean abstraction that another human can understand immediately.
We should not throw that away carelessly.
Some of the resistance will come from safety concerns. That is also legitimate. A machine-native representation that no human can inspect line by line raises serious questions for governance, certification, liability, and control.
But I think the wrong move would be to imagine that keeping everything human-readable is a durable defense.
If machine-native forms produce better software, faster reasoning, stronger validation, or lower failure rates, they will arrive. Not because they are fashionable. Because they will be useful.
And when they arrive, our task will not be to romanticize the older layer.
Our task will be to decide what has to remain legible to humans, what can safely move into machine space, and what proof we require before we let one talk to the other.
That boundary is where a lot of the next decade of software engineering will be fought.
So is this still programming?
I think it is.
But it is programming pulled upward, away from syntax and toward meaning.
The center of the profession moves from writing every instruction by hand to defining the world in which instructions are allowed to exist.
That world has rules.
It has contracts.
It has expected behavior.
It has forbidden states.
It has proofs, tests, monitors, and boundaries.
And yes, somewhere inside it there may be executable artifacts no human ever truly reads.
That does not scare me as much as it seems to scare others.
What would scare me is pretending this shift is not already underway.
The real question is no longer whether machines will help write software.
They already do.
The real question is what verification looks like when reading is no longer the method.
I think that is where the next serious work begins.