But what happens when they get really good at generating the not-so-boring bits? They're much better at this than they were a year or two ago, so it's not unthinkable that they will continue to improve.
I'm a firm "AI" skeptic, and don't buy into the hype. It's clear that the brute force approach of throwing more data and compute at the problem has reached diminishing returns. And yet there is ample room for improvement by applying solid engineering alone. Most of what we've seen in the past year is based on this: MCP, "agents", "skills", etc.
> I would code even if I didn't get paid for it.
That's great, but once the market value of your work diminishes, it's no longer a career—it's a hobby. Which doesn't mean there won't be demand for artisanal programming, but it won't power the world anymore. It will be a niche skill we rely on for very specific tasks, while our jobs will be relegated to steer and assist the "AI" into producing reliable software. At least in the short-term. It's doubtful whether the current path will get us to a place where these tools are fully self-sufficient, and it's arguable whether that's something worth aiming for anyway.
This is the bleak present and future the article is talking about. Being an assistant to code generation tools is far removed from the practice of programming. I personally find it tedious, unengaging, and extremely boring. There's little joy in the experience beyond ending up with a working product. The road to get there is not a journey of discovery, serendipity, learning, and dopamine hits. It is a slog of writing software specs, juggling contextual information and prompts, and coaxing a human facsimile into producing working software by using natural language. I dislike every part of this process. This is not the type of work that inspired me to do this professionally. Sure, every job has tasks we sometimes don't enjoy. But once you remove programming from the equation, there's not much joy in it left for me.
What plagues me about LLMs is that all that generated code is still around in the project making reviews harder as well s understanding the whole program source. What is in there that makes you prefer this mechanism instead of the abstractions that have been increasingly available since forever?
The compiler produces a metric shit ton of code that I don't see when I'm writing C++ code. And don't get me started on TypeScript/Clojure - the amount of code that gets written underneath is mindbogglingly staggering, yet I don't see it, for me the code is "clean".
And I'm old enough to remember the tail end of the MachineCode -> CompiledCode transition, and have certainly lived through CompiledCode -> InterpretedCode -> TranspiledCode ones.
There were certainly people who knew the ins and outs of the underlying technology who produced some stunningly fast and beautiful code, but the march of progress was inevitable and they were gradually driven to obscurity.
This recent LLM step just feels like more of the same. *I* know how to write an optimized routine that the LLM will stumble to do cleanly, but back in the day lots of assembler wizards were doing some crazy stuff, stuff that I admired but didn't have the time to replicate.
I imagine in the next 10-20 years we will have Devs that _only_ know English, are trained in classical logic and have flame wars about what code exactly would their tools generate given various sentence invocations. And people would benchmark and investigate the way we currently do about JIT compilation and CPU caching - very few know how it actually works but the rest don't have to, as long as the machine produces the results we want.
Just one more step on the abstraction ladder.
The "Mars" trilogy by Kim Stanley Robinson had very cool extrapolations where this all could lead, technologically, politically, social and morally. LLMs didn't exists when he was writing it, but he predicted it anyway.
Higher level languages did not hinder evaluating correctness.
Formal languages exist because natural languages are ambiguous inevitably.
Measuring performance is relatively easy regardless of whether the code was generated by AI or not.
You have to review all the LLM output carefully because it could decide to bullshit anything at any given time so you must always be on high alert.
A lot of people (me included) would have a model of what is going on when I wrote some particular code, but sometimes the compiler just doesn’t do what you think it would do - the jit will not run, some data would not be mapped in the correct format, and your code will magically not do what you wanted it to.
Things do “stabilise” - before TypeScript there was a slew of transpiled languages and with some of them you really had nasty bugs that you didn’t know how they are being triggered.
With ruby, there was so many memory leaks that you just gave up and periodically restarted the whole thing cause there was no chance of figuring it out.
Yes things were “deterministic” but sometimes less so and we built patterns and processes around that uncertainty. We still do for a lot of things.
While things are very very different, the emotion of “reigning in” an agent gone off the rails feels kinda familiar, on a superficial level.
What I worry about is that my list has gotten shorter not because everything is as it should be but because I have slowed down.
Quite a lot of things on that list were of the "The future is here but it's not evenly distributed" sort. XP was about a bunch of relatively simple actions that were force multipliers with a small multiple on them. What was important was that they composed. So the benefit of doing eight of them was more than twice the benefit of doing four. Which means there's a lot of headroom still from adding a few more things.
If AI is writing all the code, how do we keep the quality good? It's so obvious with the current GenAI tools that they're getting great at producing code, but they don't really understand the code.
We don't really know how this story unfolds, so it's good to keep a positive mindset.