The long walk away from the machine

Why letting AI write your code is just the next step in an 80 year retreat from the hardware

Every generation of programmers has been told that the new tools are cheating. The assembly programmers sneered at the people who used compilers. The C programmers sneered at the people who used garbage collection. And today, plenty of software developers will tell you that describing what you want to an AI and shipping whatever it hands back isn't "real" programming at all.

They're not wrong that something is being given up. They're wrong about it being new. The entire history of software is the history of programmers giving up control over the machine in exchange for the ability to think at a higher level. AI generated code isn't a break from that story, it's the next chapter of it.

Here's the 80 year version of how we got here.

In the 1940s programming was the hardware

In the beginning there was no software in any sense we'd recognize today. To "program" the ENIAC in the mid-1940s you didn't write anything, you physically rewired the machine, setting switches and plugging cables into patch panels. A new problem meant days of rerouting wires by hand.

Then came the punched card.. stiff paper with holes punched in specific positions, where the presence or absence of a hole in each column was the data. Feed the cards through the reader in the right order and the machine executed your instructions. Drop the stack on the floor and shuffle the order and your program was gone.

This is the floor of the abstraction ladder. There was essentially zero distance between what the programmer expressed and what the hardware did. You were not describing a computation, you were describing the literal physical state of the machine, one bit at a time. The programmer's mental model and the circuit's behavior were the same object.

Assembly.. a thin coat of paint over the silicon

The first real step up was assembly language in the late 1940s and early 1950s. Instead of toggling raw binary you could write mnemonics MOV, ADD, JMP etc.. An assembler then translated those human-ish symbols into the machine code the processor actually ran.

This was such a relief, ADD is easier to read than a string of ones and zeros but it was a thin coat of paint. Assembly is essentially a one-to-one shorthand for the machine's own instruction set. And that instruction set belonged to a specific chip. Code written for one processor's architecture was meaningless to another. Want to run your program on a different machine? Rewrite it instruction by instruction against the new hardware's manual.

So the defining pain of this era was that software and hardware were tightly coupled together. You weren't writing a program so much as writing for one particular machine. The abstraction had lifted you off the silicon by maybe an inch.

And then came FORTRAN, for the first time we let the machine write the machine code

The leap that changed everything came in 1957 when John Backus and his team at IBM released FORTRAN (FORmula TRANslation). For the first time a scientist could write something close to ordinary mathematical notation

X = (A + B) * C

and a compiler would turn that into the assembly and machine code automatically. The programmer no longer had to know or care which registers held which values.

It's hard to overstate how radical this was and how much resistance it met. The prevailing wisdom was that no automatic translator could ever produce code as tight and fast as a skilled human writing assembly by hand. Letting a compiler generate your machine code felt like handing the controls to something that didn't understand the machine the way you did. It would be slow. It would be sloppy. It wasn't real programming.

Sound familiar?


FORTRAN won anyway, because the productivity gain was overwhelming and the compiled code turned out to be good enough and then more than good enough. This was the first time programmers accepted a deal that would define the rest of the field: give up direct control over the machine code, and in return, think in terms of the problem instead of the hardware. Languages like LISP (1958) and COBOL (1959) followed close behind and each one prying the programmer further off the metal.

The crucial shift here is conceptual, after FORTRAN, you no longer wrote the instructions the computer ran. You wrote a description of what you wanted and something else generated the instructions. Every layer since has just widened that gap.

Abstraction as a way to manage our own mess

By the late 1960s and 1970s the problem had changed. Hardware was no longer the main enemy, complexity was. Programs had gotten big enough that programmers couldn't hold them in their heads.

Object-oriented programming was pioneered by Simula in 1967 and taken to its pure form by Smalltalk in the 1970s (and later mainstreamed by C++ in 1985 and Java in 1995), was a response to that. Instead of describing the computation as one long sequence of steps, you modeled the problem as a collection of objects that bundled their data and behavior together. A BankAccount object knew how to deposit and withdraw you didn't have to think about the memory layout underneath.

OOP wasn't primarily about getting further from the hardware though it did that too. It was about giving the programmer better abstractions for thinking, so they could reason about a system in terms of concepts rather than mechanics. Another rung up the ladder in a slightly different direction, abstraction not just away from the silicon but away from raw procedural detail.

Python.. so far from the metal it reads like prose

Then there's Python, first released by Guido van Rossum in 1991 and now it ranks as the most popular programing language (or at least in the top 3).

Stop and look at how far Python sits from everything below it (there are other languages that have this same properties):

  • You don't manage memory, a garbage collector does it for you.
  • You don't declare types, the interpreter figures them out at runtime.
  • You don't compile to a specific chip, the same script runs on your laptop, a server, and a Raspberry Pi.
  • You import a library and get tens of thousands of lines of someone else's work behind a single function call.
  • The language was explicitly designed to be readable and to look as much like plain pseudocode as possible. (this is uniquely python, I'm not aware of any other mainstream language with similar syntax)

A line of Python like for item in cart: total += item.price is barely encrypted English. The programmer writing it has almost no contact with what the processor is physically doing. Registers, instruction sets, memory addresses, the order of cards in the stack, all of it has been abstracted into invisibility handled by layers and layers of tooling built up over decades.

Python is closer to vibe coding than to assembly

Imagine the whole history as a single line with the bare machine at one end and pure human intention at the other.

The ladder of abstraction: the same task, printing 'hi to the world', shown from machine code and assembly at the metal, up through FORTRAN, C, Java, and Python, to 'just tell the AI what you want' — each rung hides more of the machine and moves closer to human intent.
The same task, expressed with a little less silicon and a little more intent at each level.

So how far is Python from assembly and how far is Python from describing your intent to an AI?

Going from assembly to Python is an enormous distance. You travel from manually shuffling bytes in and out of CPU registers, on a specific chip, to writing readable, hardware-agnostic, garbage-collected, dynamically-typed instructions that you barely recognize as instructions to a machine. You cross compilers, virtual machines, type systems, memory managers, and decades of accumulated abstraction.

Going from Python to "describe the feature in a sentence and let the model produce the code" is by comparison a short hop. You're already writing near-English. You already trust a giant stack of tooling you don't inspect, nobody reads the generated bytecode their Python produces, just as nobody traced the wires in a FORTRAN compiler. Karpathy's own 2023 line captures it perfectly: "the hottest new programming language is English." That's not a revolution against the trend. It's the trend reaching its logical conclusion.

By any reasonable measure of distance from the hardware, Python is much closer to vibe coding than it is to assembly. The Python programmer and the AI prompting "programmer" are standing almost next to each other on that line. The assembly programmer is way back at the other end near the bare silicon.

So is letting AI write the code "fine"?

If the only axis that mattered were abstraction, distance from the machine, the answer would be an unqualified yes. Every previous rung was met with the same complaint ("you don't understand what's really happening underneath!"), and every time the field decided the trade was worth it. Compilers won. Garbage collection won. Nobody today demands you hand-write assembly to be taken seriously. The pattern is consistent enough that betting against the next abstraction is historically a losing bet. Letting AI generate the code is simply the most recent time we've agreed to stop caring about a layer we used to obsess over.

But I'd be lying to you if I pretended this rung is identical to the others, and the term "vibe coding" itself was coined to mark exactly the difference. When Karpathy named it in February 2025 "fully give in to the vibes... and forget that the code even exists" he was describing throwaway weekend projects, not production systems. The word went on to become Collins Dictionary's Word of the Year for 2025 but the people closest to it kept drawing a careful line. As the developer Simon Willison put it, if you've reviewed, tested, and understood the AI's output, that's not really vibe coding that's just using the model as a very fast typist.

Here's the caveat.. every abstraction before AI was deterministic. A compiler given the same FORTRAN produces the same machine code every time, while compilers do have bugs and mess things up sometimes, they do not have an opinion, the translation is fixed, it's repeatable and identical for everyone who runs it, so the abstraction was a sealed box you rarely need to open. An AI is not that. The same prompt can yield different code, the code can be subtly wrong in ways the prompt never hinted at, and more importantly the generated code, not your prompt, is still the thing you actually ship and maintain. The early data reflects the growing pains.. GitClear's analysis of 211 million changed lines of code from 2020 through 2024 found copy-pasted code climbing from 8.3% to 12.3% of new lines while "moved" code, the fingerprint of refactoring and reuse, collapsed from 24.1% to 9.5% and "churn" code revised or thrown away within two weeks of being written rose from 5.5% to 7.9% all tracking the spread of AI assistants. Pair that with a run of security scares around hastily "vibe-coded" apps in 2025 and the maintainability question turns from theoretical into concrete.

So here's what the data shows and I think it's a more interesting place than a flat "it's fine"

AI writing your code is fine in exactly the way every abstraction before it was fine, as long as you treat it like an abstraction and not a magic spell. Compilers earned trust because their output was reliable and inspectable when you needed it. AI earns the same trust the same way, by you reviewing, testing, and understanding what comes out when the stakes are real, and by feeling free to "forget the code exists" when they aren't. The abstraction is sound, it's just a probabilistic abstraction instead of a deterministic one which means the human's job shifts from writing the instructions to verifying that the intent was met.. which, when you look closely, is exactly what climbing every previous ladder of abstraction demanded of programmers too.

The programmer at the punch-card reader and the programmer typing a prompt are doing the same fundamental thing.. expressing intent and trusting a system to turn it into machine behavior. The only thing that's changed in eighty years is how much of the machine we've been willing to forget. AI is just the furthest we've ever walked from it and if history is any guide, it won't be the last.


And you can already see the next rung, models as infrastructure. Why ship the generated code at all? Ship the prompt, let the model be the runtime, and let code become one more intermediate artifact nobody reads, like the assembly your compiler quietly produces today. Someone is almost certainly building this right now. And when it arrives, we already know exactly what the critics will say: it isn't real programming.