On AI for Programming, or: Wading through the grime and the slop and the filth.
Motivation for writing this document
So, for a little while I have felt the presence of AI as it pertains to programming grow inexorably. It was slow at first, a few tools to auto-complete, then Claude code started popping up and creating a whole class of new programmer, but it seems to have accelerated near-continuously to the point where my employer is feeling the need to push it as a primary method of "evolution". This has made me profoundly uncomfortable, and I needed to get some thoughts out of my head onto paper, as it were.
Forward and back, then go forward and back
I think it might be worth tracking my history of using AI in my workflow as far back as I can remember, to trace how my relationship has changed with it over time.
This will be sorta a stream of consciousness rather than any sort of thesis, I'm just trying to remember what I used and when I started using it.
2018: Tabnine - 2024 Github Copilot
To my knowledge, tabnine was one of the very first "AI-assisted" programming tools. At the time it was a very simple completion engine, and if I recall correctly, I had it wired up into vim to provide tab-completion. I remember it being very awkward to configure, requiring magic strings to be pasted in insert mode. Janky, but a first step.
I had to do some actual digging to figure out when I started using copilot - and my first receipt appears to be from about April 2024.
Pretty sure I started using it for what I would continue to use it for over the next 18 months - primarily, autocomplete. The same thing
as tabnine. For example, I could write s3Cli.send and I get a basic PutObject command filled out for me. Sometimes I could get
an entire function autocompleted exactly as I wanted to write it. Sometimes it would insist that no actually it's s3Cli.putObject because
so much of its training data would reference that function.
At the time, this was in the grey area of corporate allowances. I had a personal licence, and there was no word from on high about it being either endorsed, nor forbidden. Thus I carried on, and ended up as one of the first people in my business unit "trialling" the product. Please ignore that I was using it already.
Early 2026: Agentic experiments
Early in 2026, "OpenClaw" was released, promising to allow you, yes you, to run an AI agent on your hardware and have a little assistant to handle tasks. Whilst this sounded like a security nightmare, I decided to try it out. Yep, nightmare. The software barely worked, and would write its own bash scripts and such.
To say this rubbed me up the wrong way would be an understatement, but I still saw some promise in the idea. Around this time, corporate was also starting to beat the AI drum, so I decided that I would do it myself. Enter, Lobber.
I built my very own OpenClaw alternative from first principles, being forced to learn how these systems handle contexts, memories, identity and so on. I ran lobber on a VM for approximately 8 months before decommissioning it. During its lifespan, I talked to it a lot but found it profoundly lacking in things to... do. Sounds weird, I know. But I had a multitool at my disposal and could not for the life of my find a nail to use the hammer attachment even. So it was just a glorified chatbot at the end of the day.
What did I want from lobber even? I genuinely think I built it purely out of pre-emptive spite, seeing the way the industry was leaning and requiring ammunition before the fight began. Quite a cynical motivation, I know. But I wanted to try it in earnest, and know first-hand whether this was everything it was hyped up to be. Or otherwise, have the firepower to bring to bear against people that would force me to use it.
I also tried "agentic development" tools like Xiaomi's mimocode and the infamous Claude code. My primary testing ground was a notoriously difficult task, fediverse frontends. Fediverse APIs are obnoxious at the best of times, with many edge cases and sub-functionality within sub-functionality. I found that all of these systems could make frontends that appear on first glance to be functional. They did, in fact, work. But looking under the surface I found patterns that went out of style a decade ago, websocket management that I'd consider a mark of the antichrist, and a distinct lack of anything having being "engineered" in any way.
I promptly stopped using these systems after this experiment.
AI in the current landscape
The catchphrase you'll hear online right now is that "every developer is using AI. Those that say they aren't, are lying". This phrase serves a dual purpose. The first one is that of promotion. A lot of developers right now are employed in the creation of AI. They have a vested interest in its success, and creating the image of "the future" is how they get investment and job security.
The second is a little more insidious, I think. Just about every developer probably is, but perhaps not of their own volition. Many corporations of late have started mandatory AI usage (which is gamed by techies as any such metric will inevitably be).
So, given that I have used it, and appear to be in the group for whom it will no longer be my choice, I think I should put into words the pros and cons of AI as it stands right now.
Things I think it's pretty ok at
If you really do just want the skeleton of something to go off, it's usually pretty alright at that. The more niche your field is, the worse it'll be. But "can I have the cloudformation yaml for a lambda triggered by SQS" will generally get you most of the way there. And you were just going to copy the same yaml you used last time anyhow, right?
Digging through documentation for definitions can be pretty ok as well, as much as I find cloud Jira to be icky, being able to expand acronyms based on external documentation is undeniably useful.
Things I think it sucks at
Architecting a solution. There is no easier way to realise that these models do not think than trying to create a system wholesale and watching the agent make thousand-line files and re-implement the same function all over the place. It does not make connections like "huh this can be refactored and I can extract this to a function" - it just implements.
Dealing with legacy systems in any capacity. Especially ones where library APIs may have changed multiple times in the intervening years between the legacy system's creation and the current day. I have lost track of the number of times I have been working on a legacy java project and had copilot jump in with "have you tried this function that existed in a library version 10 years ago that I have in my training dataset?".
Niche domains can also prove a stumbling point as the model confidently makes up internal APIs to call, or thinks it can apply a one-size-fits-all approach to a process that even those that made the requirements barely understand. Have an arcane internal format for aspect ratios? The AI knows for sure how it works! And it'll make up words that sound right but just are not.
Things that I am profoundly disturbed by
I have observed the mental faculties of myself, and those around me, decline with the (over)use of AI. I was once one of those insufferable arch Linux users in my mid-teens, which is a pretty steep learning curve for a teenager. The arch wiki was my salvation, I could search for effectively anything I wanted and probably get the building blocks for whatever I was trying to do.
Contrast that with my recent attempts to learn nix, a similarly impenetrable learning curve. I found myself /far/ more ready to give up my search for information and just go "hello Mr AI, how do i write a flake.nix?". I had the skills to do this myself, why have I lost the motivation to actually employ them? And once you start doing it, you end up on the proverbial slippery slope. "Oh I'll just generate the skeleton flake then research the rest myself!" I'd say to myself, run into a brick wall face-first and go "uhhh Mr AI how do I make bundler find libffi?". None of these are uncommon or unsolved problems. I did not need a chatbot for them.
I have also witnessed colleagues triage bugs, not by attempting a reproduction of the issue, but by asking copilot to take the (obfuscated) error message and diagnose what it means. Debugging an old codebase is one of the fastest ways to understand it better as you are forced to trace a stack dump through functions to figure out what's breaking and in what way - can I have any hope that the codebase will not rot into incomprehensibility if even the most senior of engineers no longer has the willpower to read a stacktrace?
These symptoms appeared fast and are very hard to cure - the human brain is remarkably plastic and will happily purge anything it deems to no longer be required. I came of age during the early days of the smartphone, and my brain never got that part that remembers phone numbers. Because it doesn't need to. If I were to lose my address book, I would be entirely lost. I feel that these symptoms are the same phenomenon, where the brain starts removing the parts that deal with analysing functions and stacktraces once it thinks the skill is no longer required.
If this is what happens to senior developers with years of experience, what will the juniors be learning? What will the products I have spent months of my life architecting look like when they are passed down to people who have no interest in understanding it? Who do not see it as anything but a blob to be managed by an agent?
Something of a statement of intent
I hold something of a niche belief.
I believe that programming is a trade. Not a strict field of engineering, not strictly an art form. Somewhere between the two. Sitting in the same space as woodworking (this is my hypothesis for why so many programmers go on to become woodworkers or glassblowers when they burn out).
This means, naturally, that the implementations of the trade can sit between mass-production and artisanal. IKEA has a place in this world, as does this lovely hardwood table carved by my late grandfather. Both have merit, both have use.
C-suite executives seem to believe that all programming is on the IKEA end of that spectrum, where fundamentally you arrange blocks in a way to fulfil requirements. And for a lot of situations this may even be true.
However, the skillset of the artisan is in taking novel requirement and creating a solution that a million Billy bookcases cannot be bodged together to create. You cannot arrange Blahajs in a way to standardise a process used since the 50s that is only passed down in practice rather than theory.
Attempting to replace your artisans with your IKEA haul is folly, and will end in disaster as the cheap plywood of this stretched-too-thin metaphor was never meant for the problems that need solving, for the processes that need automating. You will create a leviathan of Claude commits that are technically correct but add up to a spaghetti junction nobody understands, and then you are locked into continuing to use AI as it is the last bastion of faux-"understanding". And then what? Your sensitive parts are locked in a vice by American billionaires and you've nothing left you can do.
As such I believe it to be something of the duty of the responsible techie to support human-made projects. Support the next generation of developers. Don't let the rapidly dwindling candle of our trade be extinguished entirely by those who do not understand what we even do.
Why does corporate pushing for it unsettle me so?
Because it's another step towards the omni-mediocre developer.
We started with backend developers, and frontend developers. Frontend developers lean into the humanities more than their more mathematical brethren, and are fewer and harder to recruit. As such, over time backend developers became expected to know at least rudimentary frontend development. CSS-in-JS did not appear out of nowhere, it's a cry for help from someone forced into a field they did not expect to be in. And lo, the full-stack developer was born.
Later on, companies decided that operations teams were no longer worth having. Probably too high-turnover, too much work recruiting for them. But the full-stacks already know how their system is intended to be run, let's integrate them into the workflow! And lo, DevOps as a profession was born.
And in recent years, with as many high-profile vulnerabilities as there have been, security has also been added to the developer's remit. What do we even call them, at this point? DevSecOps? Better not, they might get ideas about asking for more money for the expanded job description.
And this week, every single tester in my company was made redundant. I saw this coming about a year out and frantically tried to mitigate the impact, but the impact came all the same. In the same breath, the leadership team touted the power of AI. I witnessed with my own eyes the obliteration of an entire practice and the expansion of my job description.
No person on the face of this earth can be genuinely good at backend, frontend, operations, security /and/ testing. Nobody. Not a soul. But we do have the machine. The machine may be mediocre at all things, but that's all you need to get by, right?
So what is the incentive here? If you're using AI for testing already, as we all know developers should not test their own code, you may as well use it for some frontend work, right? The incentive is to hand over as much as you can to the machine and let /it/ handle everything. Because nobody is asking for any more than that, nor do they give you the time to genuinely learn how to be passably good at it.
The incentive is to be just good enough. Take your paycheck and go back to sleep, and hope the next round of layoffs passes over you.