22 comments

[ 2.7 ms ] story [ 49.0 ms ] thread
I've been seeing teammates go from promising juniors to people who won't think, and I've tried hard here to say what I think they're going wrong.

Like the great engineers who came before us and told us what they had learned, Rob Pike, Jez Humble, Martin Fowler or Bob Martin, it's up to those of us with a bit more experience to help the junior generation to get through this modern problem space and grow healthily. First, we need to name the problem we see, and for me that's what I wrote about here.

There used to be a time when you needed to be very skilled woodworker in order to make nice cabinets. There still are, but the number of machine / CNC made cabinets outnumber artisanal 100% hand-made cabinets by some incredible number. For every masterpiece made by a Japanese cabinet maker, imagine how many Ikea cabinets there are out there...

And that's how I believe software engineering will end up. Hand crafted code will still be a thing, written by very skilled developers...but it will be a small niche market, where there's little (to no) economic incentives to keep doing it the craftmanship way.

It is a brave new world. We really don't know if future talent will learn the craft like old talent did.

AI will hopefully humble so of the people I work with.

The people who understand nothing about business, yet you can't talk to because they think gifted for being able to write instructions to a computer.

The people spin out new frameworks every day and make a clusterf*ck of hyped and over-engineered frameworks.

The people who took a few courses and went into programming for money..

I went into software because I enjoyed creating (coding was a means to an end), and I always thought coding was the easiest part of software development. But when I get into corporate work, I find people who preach code like religion and don't even care about what is being produced, spend thousands of hours debating syntax. What a waste of life, I knew they were stupid, and AI made sure they knew as well.

I find that AI is really good at the easy stuff like writing tests for simple class without too many dependencies that we have all written hundreds of times.

Things go wrong as soon as I ask the AI to write something that I don't fully grasp, like some canvas code that involves choosing control points and clipping curves.

I currently use AI as a tool that writes code I could write myself. AI does it faster.

If I need to solve a problem in a domain that I haven't mastered, I never let the AI drive. I might ask some questions, but only if I can be sure that I'll be able to spot an incorrect hallucinated answer.

I've had pretty good luck asking AI to write code to exacting specifications, though at some point it's faster to just do it yourself

This is a really good post. I'm a naturally controlling person, and I care about my craft a lot, so even in my recent dabbling (on a ~3000 LOC project) with agentic coding, one of the things I naturally did from the start was not just skim the diffs that the AI generated, but decide for myself what technologies should be used, describe the logic and architecture of the code I wanted in detail — to keep my mental model fresh and accurate — and read every single line of code as if it was someone else's, explicitly asking the AI to restructure anything that I didn't feel was the way I'd implemented it — thus ensuring that everything fit my mental model, and going in and manually adding features, and always doing all debugging myself as a natural way to get more familiar with the code.

One of the things I noticed is that I'm pretty sure I was still more productive with AI, but I still had full control over the codebase, precisely because I didn't let AI take over any part of the mental modelling part of the role, only treating it as, essentially, really really good refactoring, autocompletion, and keyboard macro tools that I interact with through an InterLISP-style REPL instead of a GUI. It feels like a lever to actually enable me to add more error handling, make more significant refactors for clarity to fit my mental model, and so on. So I still have a full mental model of where everything is, how it works, how it passes data back and forth, and the only technologies I'm not familiar with the use of in the codebase are things I've made the explicit choice not to learn because I don't want to (TKinter, lol).

Meanwhile, when I introduced my girlfriend (a data scientist) to the same agentic coding tool, her first instinct was to essentially vibe code — let it architect things however it wanted, not describe logic, not build the mental model and list of features explicitly herself, and skim the code (if that) and we quickly ended up in a cul de sac where the code was unfixable without a ton of work that would've eliminated all the productivity benefits.

So basically, it's like that study: if you use AI to replace thinking, you end up with cognitive debt and have to struggle to catch up which eventually washes out all the benefits and leaves you confused and adrift

I mean, yes. And also; it's the age old problem that arises every time a new technology arrives in full: it requires a steadier-than-priorly hand in order to not have ballistic effects on society. This goes for books over what-my-betters-told-me, swords over flint-blades, automotive cars over horse-carts and indeed; ALL technology. New tech of any real substance invariably carry the need for cultural shift towards a more advanced stance that allows for the gainful use of said technology at scale.
For better or worse I’ve been finding it difficult to stay motivated at times for sharpening my craft. I’m currently reading Learning Go 2nd and it’s cool learning the idiomatic ways to write code in a language. However part of me feels like even if I strive to write “clean code”, now the bottleneck seems to be shifting to reviewers time and expertise.

So I fear I’m fighting a losing battle. I can’t and don’t want to review everything my coworkers put out, and code has always been a means to an end for leadership anyways so it seems difficult to justify carving out time for the team as a whole to learn, especially in the age of genAi.

I'm a 20+ years programmer working with my colleagues who are 2-5 years of experience. I could see they had accepted AI generated tests which are testing solely the mocks. This is quite annoying, because for me, when I want to finish a task properly, I have to write tests from scratch. I'm also using the same AI tool, but I want to use it differently, as a "copilot" and not the "main pilot"
At some level it is true that AI is a bit like adding electric engines everywhere.

Including gym equipment.

Music to my ears, can't wait this slop generator to flop.
What actually happened is that AI shifted / moved the valuable points to master
In complete irony, I got back to reading actual docs for Python, React, Scala (my stacks) because I do NOT like being spoon-fed slightly-off answers.

I have a feeling that the skills for fixing up AI slop will be in-demand quite soon.

But, more to the point - AI code is legacy code.

> Claude wrote me Go tests that passed. They were beautiful, and they were worthless. They all collapsed to true == true.

My favorite one of these is when I was having Claude write a nix derivation to package kustomize at 4.5.5 and instead of getting the correct source version and building it, it just set some build args on the latest version to override the output of the --version CLI flag.

To me it seems it happened the other way around: a reduction in the valuation of mastery preceded, and facilitated, the acceptance of LLM output as "good enough".

What was called "move fast and break things", is one example. This development model leaves behind a trail of shit, that is poorly integrated and often, fully understood by no one.

Like vibe coding, this is all great until something doesn't work (not IF something doesn't work, but UNTIL).

This failure to appreciate mastery is illustrated in even earlier "business model" strategies, such as elimination of large corporate R&D laboratories, and the LBO raiders.

It's widely understood that every product and service in the current era is going to shit (certainly for the users, even if not for the ownership). Toasters built in the early '50s still work, toasters built today are designed for the dump. This isn't a problem with toasters, it's a problem with the business model of unrestrained capitalism.

I might half agree with the premise. I've heard some version of the phrase "make it work, then make it right" and sure, if you only vibe code, you will be left with ... vibes.

I find that when I'm reaching for AI it's because I'm actually trying to decide if I want to implement the idea I have, and need a PoC vs. expecting production ready things. For example, I was working on a UI and wanted to be able to "swap" two ul lists in JS. Not too hard of a thing to do, but I didn't remember the syntax, etc, and instead of hand writing, I asked the AI to do it.

It worked. The code was insanely overwrought and iterating over each list item 1 by 1 etc etc etc. But that's fine, I'm still not sure the "swap button" in the UI is the right UX, so I put a todo and am working on the "right problem" instead of banging out a clean list swap function. The mastery I'm seeking is not "most elegant usable list swap function, with maintainable code" but instead "Is this the best UX?" AI slop helped me stay in flow state towards that mastery.

In recent weeks, I have made huge changes to my main codebase. Pretty sweeping stuff, things that would have taken me months to get right. Both big, architecturally important things, as well as minor housekeeping tasks.

None of it could have been done without AI, yet I am somehow inclined to agree with the sentiment in this article.

Most of what I've done lately is, in some strange sense, just typing quickly. I already knew what changes I wanted, in fact I had it documented in Trello. I already understood what the code did and where I wanted it to go. What was stopping me, then?

Actually, it was the dread loop of "aw gawd, gotta move this to here, change this, import that, see if it builds, goto [aw gawd]". To be fair, it isn't just typing, there ARE actual decisions to be made as well, but all with a certain structure in mind. So the dread loop would take a long long time.

To the extent that I'm able to explain the steps, Claude has been wonderful. I can tell it to do something, it will make a suggestion, and I will correct it. Very little toil, and being able to make changes quickly actually opens up a lot of exploration.

But I wonder if AI had not been invented at this point in my career, where I would be. I wonder what I will teach my teenager about coding.

I've been using a computer to write trading systems for a long time now. I've slogged through some very detailed little things over the years. Everything from how networks function to how c++ compiles things, how various exchanges work on the protocol level, how the strats make money.

I consider it all a very long apprenticeship.

But the timing of AI, for me, is very special. I've worked through a lot of minutiae in order to understand stuff, and just as it's coming together in a greater whole, I get this tool that lets me zip through the tedium.

I wonder, is there a danger to giving the tool to a new apprentice? If I send my kid off to learn coding using the AI, will it be a mess? Or does he get to mastery in half the time of his father? I'm not sure the answer is so obvious.

very good articulation on the problem. My bet is that it is probably fine in the sense that the mastery itself is not going to be relevant.

I want to view AI coding as invention of new coding tools, at least in the way you described. I (hope) it will be more like punch-card->assembly-> BASIC/C -> scripting language -> some sort of well-structured natural language.

> Claude wrote me Go tests that passed. They were beautiful, and they were worthless

Their ability to look correct exceeds their ability to be correct. Optimized for form more than function. Like politicians and management at large companies. Like the rote student who can be correct, but wont know why. Being fair though, it is a useful tool among many others in our toolbox.

Yup, I agree with the author 100%. By far the worst part of AI code generation is the inability to discern old and deprecated APIs/syntax/workflows of tech stacks that are constantly changing.
Not even mastery. The other day I was trying to figure out how to pass an external label to Prometheus alert rules when unit testing the rules with "promtool test rules". Man, all the models gave all kinds of hallucinated answers, and I had to resort to reading the promtool code. In the end, mastery means we get apply our skills to solve new problems, yet in the current state AI can only interpolate already solved problems.
I wrote a blog post looking at a similar vein: https://www.dcaulfield.com/mastery-4-ai

If everyone uses AI, then the standard of mastery hasn't lowered - it's increased!

We're now caught in a dilemma: Do we play the short term game and use AI at the expense of our skills, or do we play the long term game and avoid AI where possible to build up expertise while risking being out-competed by everyone else who is using AI?