The cost of shoring up behavior with tests ahead of a restructure has gone down because of AI.
The cost of implementing a zero downtime migration has gone down because of AI.
A big part of the rust hype has been the low cost of restructuring within an application, even before AI. And now even more so.
The opportunity cost of not being able to safely restructure has gone up substantially.
This is the number one thing I optimize for now: the ability to quickly and safely change significant parts of the code and product.
cassianoleal · 2026-06-28 19:00:57 UTC
> This is the number one thing I optimize for now: the ability to quickly and safely change significant parts of the code and product.
This was always a good thing. Its value has nothing to do with the advent of AI coding.
> The opportunity cost of not being able to safely restructure has gone up substantially.
This bit is contradictory with everything else you said. Prior to AI coding it would take a lot longer to perform restructures. If anything, the thing you're now optimising for has gone down in value. It's still valuable, but perhaps a little less.
phamilton · 2026-06-28 19:10:23 UTC
I'm not talking about time. I'm talking about safety. The amount of times I've seen "I refactored it, but I'm not confident enough to take it to prod" is significant. Being able to go faster but still not ship it is the huge opportunity cost.
sublinear · 2026-06-28 20:00:35 UTC
In the broader corporate world, that's not "opportunity cost". All changes are considered "risk".
All deployments must be approved by an advisory board. All work must originate from a clear business need. Analysis of those needs is not concerned with implementation, least of which whether "AI" is used.
What matters far more is that a contract requires work to be done by a deadline. Those deadlines are driven by policy. There will be no adjustment to policy unless tangible benefits are shown from more frequent deployments of code.
I gotta tell you that's extremely unlikely if you're already shipping every other week at the end of the sprint. Most of that sprint is spent in meetings, not writing code. Nobody is doing big refactors because it wasn't built so fast to require them. There's some technical debt, but nothing so severe. Those meetings are preventing risk, not wasting time. The bottleneck is a feature, not a bug.
If you think the future of dev work is to be a bureaucrat, you're right! It looks like the rest of the world outside of SV is ahead of the curve and living in the future.
phamilton · 2026-06-28 20:10:40 UTC
That's not at all what I meant.
I mean "We can't build X because our code structure makes that difficult" has an opportunity cost of the value of X.
I don't think the future of dev work is being a bureaucrat. I've done more rigorous engineering the last two years than I did previously. I'm more confident in the things I shop and they were built in a fraction of the time. It's a bright future for software engineering.
cassianoleal · 2026-06-28 20:20:21 UTC
Time, safety and cost are one and the same. Not safe enough? Spend more time increasing confidence. Taking too long? Cheap out now and pay the price later due to added risk.
All of that is orthogonal to AI. All AI did was accelerate the typing code part - which was never the bottleneck or a very significant cost to begin with.
mohamedkoubaa · 2026-06-28 21:14:23 UTC
Ironically, AI assisted/generated code is not trending in the direction of the ability to safely and quickly change. Especially when piloted poorly
cassianoleal · 2026-06-28 21:37:07 UTC
I hear you! I also actually find it a lot more difficult to ensure proper guardrails are in place to keep the agents doing good engineering work.
joshka · 2026-06-28 23:34:38 UTC
Citation needed.
But in seriousness, this intuitively feels like something (as phrased) that would be easily influenced by loud noise and quantity rather than hard facts. The "piloted poorly" part is applicable to any tool use. AI is no different there other than its adoption rate.
majormajor · 2026-06-29 01:06:19 UTC
The pattern I observe is: "write code, write test, make things green"
This is different in two ways from the classic TDD red-green-refactor suggestion:
1) they don't start with the test first, so the tests that get implemented are after writing the code, and run the risk of the model attention being now more influenced by the just-written code than the original spec
2) they finish when everything is green and don't followup with the "refactor" step unless manually prompted (either directly or indirectly by your own scaffolding/rules/whatever). this results in frequent hyper-local non-ideal-longterm fixes for things that went wrong in the first shot at writing the code pre-test-writing.
(As always, the only person who can ensure the code landing in your repo is good is you.)
joshka · 2026-06-29 03:20:25 UTC
But here's the rub - if you want your clanker to do those steps, it's usually a simple matter of adding them to your AGENTS.md and then it always does them.
I'm a big fan of the characterization step step being added. And it can be reasonable to add this before or even after the fact as a commit prior to your actual commit (assuming you're familiar with using tools where that's easy to do - e.g. jj or git with rebase). And the agents can do this - they just don't tend to without you saying to do so.
A lot of engineering practice comes from choosing which elements are reasonable to use given the context of what you're building. Providing that is your job. When you do that poorly, you get poor results. But garbage in garbage out has always been a thing. Any advanced automation amplifies ambient assumptions
xboxnolifes · 2026-06-29 03:08:53 UTC
>> This is the number one thing I optimize for now: the ability to quickly and safely change significant parts of the code and product.
>This was always a good thing. Its value has nothing to do with the advent of AI coding.
The value of type safe code did not go up, the cost of development speed has gone down.
samrus · 2026-06-28 20:31:27 UTC
Your increasing thrash betting that AI will fix it for you. The only thing your getting in return is not having to think that hard.
It doesnt cost that much time or effort to think hard, so you will be outcompeted by people levergaing AI as much as you, but thinking enough to not have it be thrashing around
rednb · 2026-06-28 20:52:19 UTC
> the ability to quickly and safely change significant parts of the code and product.
Hum, this reminds me something... "O: open to extension, closed to modifications". Old things are new again.
From context efficiency with approaches such ad DDD and clean architectures, all the way to items such as this one, AI is not creating new tradeoff, it just acts as a multiplier, multiplying productivity for teams doing things right, and multiplying debt for teams having a low quality bar as far as design and architecture are concerned.
rzmmm · 2026-06-28 23:24:01 UTC
Over the last couple months I've seen the debt multiplication in some OSS projects. It's like premature aging of a codebase.
phamilton · 2026-06-29 04:06:38 UTC
> Old things are new again.
This is exactly how I've felt. I've read some many old papers and books and found great techniques that are even more applicable than ever.
lmm · 2026-06-29 00:47:09 UTC
> The cost of restructuring has also gone down.
> The cost of shoring up behavior with tests ahead of a restructure has gone down because of AI.
Disagree. The growth in brittle AI-generated tests means restructuring is more costly than it was before. Pruning your test suite so that it tests the essence of the problem and not the incidental design decisions is something AIs aren't yet capable of.
chowells · 2026-06-29 02:30:59 UTC
Oh, it's worse than that. I've seen a rise in mutation testing, intended to ensure any change in implementation is caught by tests. Think about that for a moment. It's giving a fancy name to creating brittle tests than fail if any line of code is changed.
And this is seen as a good thing, because LLMs are really bad at confining their changes appropriately. Testing is really in a dark place right now.
majormajor · 2026-06-29 01:02:18 UTC
> The cost of shoring up behavior with tests ahead of a restructure has gone down because of AI.
Yes.
But the ease of not doing that and instead just getting a brittle set of three-quarters-baked tests is extremely high! And many people seem happy to go from "a few human-written mediocre brittle tests" to "a bunch of AI-written mediocre brittle tests" because it is an objective improvement and the people who weren't avoiding speculative structure and looking for the write boundaries before are happy to also not do so no.
So completely agree with the "take advantage of the tools this way" but I also wouldn't claim it's a reason to no longer worry about if you're building the wrong castles in the sky too early, because perfect refactor-proof testing contracts are still usually pretty hard to design.
phamilton · 2026-06-29 04:05:08 UTC
> perfect refactor-proof testing contracts are still usually pretty hard to design
Not sure about hard, but definitely rare and we as an industry are under-skilled in these areas.
We have decades of research and tools for testing and verification of software. Property tests, dependent types, formal verification and proof, etc. The paths have been there, we have just collectively prioritized other things.
It requires an intentional shift in how we design and build. That shift is the harder part.
ffsm8 · 2026-06-29 08:56:56 UTC
> The cost of implementing a zero downtime migration has gone down because of AI.
You either don't know what that technical term means or you're just wrong. AI does not meaningfully move the needle on that. It only makes backwards compatible deployments easier insofar you're able to do the overhead for splitting the change with less effort then before.
phamilton · 2026-06-29 15:19:24 UTC
I've always known how to do zero downtime migrations. The question has always been "Is the engineering cost worth it?"
> It only makes backwards compatible deployments easier insofar you're able to do the overhead for splitting the change with less effort then before.
Yes. That reduces the cost of implementing them.
To be clear, I'm not talking about "Split my db migration and my code that depends on the new table". I'm talking about things like "Set up dual writes between an old database schema and a new database schema with a thorough test suite and do shadow reads against both datasets in prod to do differential testing". That's nontrivial engineering effort that would definitely warrant a discussion in the past. Today we just do it. It's fast and lowers risk.
sebastianconcpt · 2026-06-28 18:59:29 UTC
Seeing running software as an asset is the right approach.
But the costs of executing and even re-doing things went significantly down.
The costs that didn't went down are the ones of breaking the chain of trust to a predictable outcome. A specific version of some running software accumulated trust. If you rewrite it from scratch that capital is reset on release.
zephen · 2026-06-28 19:12:34 UTC
Nothing I have read by Kent Beck has ever suggested that he would be useful in a chip company, where lots of people toil for a long period of time in order to produce something that no customer can possibly see until it's finished, and that must be sold in quantities of millions in order to make money.
marifjeren · 2026-06-28 19:15:36 UTC
Interesting. How do chip companies plan such projects? Do they use agile, waterfall, or some other non-software-industry frameworks?
ajb · 2026-06-28 19:31:41 UTC
They (or at least some of them) use waterfall - the real waterfall, not the bogeyman invented by agile consultants.
zephen · 2026-06-28 19:41:08 UTC
(Some) chip companies have jumped on the agile bandwagon for (some) tasks.
It's always interesting to read about some chip company or another making some agile move, when the reality is that they were already doing about as many agile things as possible before agile was a thing. (For example, a management commitment to "shift left" when they have always been about significant up-front testing and feedback.)
In many, if not most, cases, the testing software is so huge that at least some of it needs to be tested itself. That can certainly benefit from agile.
But the overall process more resembles traditional waterfall. You have several definite final endpoints, and although you can make subsequent changes, those are expensive. Also, you have a silicon budget, and a pin budget, and a heat and power budget. At the end of the day, you are producing something physical with real-world physical constraints that (a) cost real money, and (b) can't be altered by just telling your customer to add more RAM or a bigger processor.
Also, in general, although designers will write their own little unit tests for a few things, it is best practice to insure that the real tests are performed by internal organizations that are different than the organization the designer is in.
I think that subconsciously, he truism that it is easier to work with and reason about a system that is already working, and to keep it working, than to get it working at all to begin with, drives a lot of the methodology.
The designer might focus on tests to insure that things work well enough to see some results, so things can be hooked up and system tests performed earlier. In one sense, this is a shift left -- the validation people and the people writing software for the chip can get started sooner than they would have otherwise, even if it's a bit frustrating because not everything works off the bat.
But the real torture tests are typically written by the dedicated verification and validation teams. Those are really different skills than design.
marcosdumay · 2026-06-28 21:37:59 UTC
Just to point, but shifting left isn't agile at all. In fact, it's slightly against development agility.
It's just a good engineering practice, that is more than useful enough to compensate for any loss of agility it may cause.
zephen · 2026-06-28 22:12:11 UTC
On the one hand, I agree.
On the other hand, like a lot of other good ideas, the agile community has claimed this. A quick google will show that many claim it is a "core agile idea."
dpark · 2026-06-29 20:25:32 UTC
It’s absolutely an agile idea. The core of agile development is the ability to iterate quickly. Shift left for certain things enables the cycle to shorten and accelerate iteration.
zephen · 2026-06-30 02:58:14 UTC
The useful core idea of "shift left" is early collaboration between development and various testing functions.
But, again, that was being done in many organizations (and for sure, in most successful chip companies) well before anything was ever labeled agile.
dpark · 2026-06-30 03:10:25 UTC
I agree that it was done by many organizations before “agile” but that’s true of all agile practices. Agile is a philosophy and a collection of tools. None of the tools are new though.
zephen · 2026-06-30 03:40:59 UTC
> that’s true of all agile practices
Which is what, honestly, makes the term essentially meaningless.
To the extent that parts of agile are and have always been "best practices" we already had a term for those.
fmbb · 2026-06-28 19:29:35 UTC
Well he makes software and writes about software development doesn’t he?
Hardware has some hard limitations. The reason software was even invented at all was precisely to escape those limitations.
zephen · 2026-06-28 19:49:40 UTC
> Well he makes software and writes about software development doesn’t he? Hardware has some hard limitations.
Right.
> The reason software was even invented at all was precisely to escape those limitations.
But the methods which are useful for hardware are also often useful for software. Most of the useful parts of agile were already practiced well before that was a name for anything. And the demonization of the straw-man version of waterfall in order to sell more agile consulting has led to some serious misconceptions of what waterfall really is and what it is really capable of and useful for.
The initial impetus for what became known as TDD was software maintenance, and it makes sense there.
But most TDD practitioners are nowhere near as good at real testing as the waterfall test practitioners who understand that a single missed testcase could delay a $10 million project by six months.
And this is why, even in the realm of software you still see serious efforts for aviation and nuclear power plants, and other things with real-world consequences, using more traditional methods.
fmbb · 2026-06-29 11:02:31 UTC
I have not seen Kent Beck argue for eXtreme Programming or other Agile methods in nuclear power plant software or aviation. These are niche industries and constitute a vanishingly tiny part of all the lines of code out there I presume.
The fact that short iterations adding features incrementally leads to better outcomes for software project is something professionals have known and argued for since the 1960s.
zephen · 2026-06-29 11:32:46 UTC
> The fact that short iterations adding features incrementally leads to better outcomes for software project is something professionals have known and argued for since the 1960s.
And practiced by software professionals since the 1960s. For maintenance. Even for aviation and nuclear. But in those industries, you're going to have a clear case, better documentation, and not be trying to "sprint."
Again, many truly best practices well predated XP/agile, and were subsumed into it. The real problem with XP/agile is the dogmatic straw-manning and demonization of other good practices that have their place, such as waterfall and exploratory programming. YAGNI, in particular, is more often used as a cudgel to shut down useful learning and exploration than anything else.
toast0 · 2026-06-28 19:49:53 UTC
> no customer can possibly see until it's finished
I'm sure lots of chip companies don't share their work in progress, but it's not impossible. Sharing simulations and prototypes and engineering samples can and does happen. You've typically got to be a big customer, of course.
But yes, insights for an industry with relatively small costs for change don't apply easily to an industry with large costs for change, and often vice versa.
zephen · 2026-06-28 20:24:50 UTC
> You've typically got to be a big customer, of course.
Yes, if you're a big enough customer, you might essentially be part of the design team.
> Sharing simulations and prototypes and engineering samples can and does happen.
Simulations aren't the thing. They don't go fast enough to solve anybody's problem. To your point, if a customer is part of the design team, then yes, they can, at that point, help to debug, or possibly even get started on their own dependent designs. (Part of the shift-left I talked about in another comment.)
I'm not sure what you mean by "prototypes" but "engineering samples" are essentially the finished product, done after all the work I described.
Yes, they may have bugs (or they might just not have passed validation and ESD testing yet), but that doesn't alter the fact that a waterfall effort happened before they were delivered.
> But yes, insights for an industry with relatively small costs for change don't apply easily to an industry with large costs for change, and often vice versa.
The problem with indiscriminate use of agile is that, while, yes, the software industry has relatively small costs for change, it has traditionally had huge costs for the initial delivery, and many agile proponents don't properly segregate those two cases.
If LLMs live up to their apparent promise, then, of course, the equations around the huge costs for the initial delivery could change dramatically.
Of course, the same LLM promise means that the strict definition of TDD (tests written first) is also irrelevant, and perhaps even counterproductive.
geetee · 2026-06-28 19:13:23 UTC
[flagged]
mh2266 · 2026-06-28 19:18:52 UTC
I fed it into Pangram and it came back as "70% AI generated".
I do feel it's better than some of the pure slop out there, but it still feels pretty sloppy. And I know that this author can write, so if this really was partially done with AI, it's disappointing.
svat · 2026-06-28 19:27:55 UTC
I think it's the latter. I find the introduction (written by Kent Beck) easier to understand than the rest of the article (which he says is AI-written: "genie-generated description of YAGNI").
In particular writing like this is just annoying:
> Perfect foresight doesn’t save you, because the discounting doesn’t care whether you were correct. It cares that you sequenced the cost ahead of the return. The gap between the two is the loss, and you opened the gap on purpose.
saulpw · 2026-06-28 19:59:44 UTC
This sounded like generated text to me. "The gap" etc
temp_praneshp · 2026-06-28 20:00:14 UTC
[flagged]
dang · 2026-06-28 23:10:38 UTC
You can't post like this here, and we ban accounts that do, so please don't.
Yes the more I read it, it's not a cohesive argument. Some of it seems contradictory. It's a word soup with lots of compelling sentences.
antonvs · 2026-06-28 21:14:30 UTC
This article is mostly AI slop. It’s very recognizable, and that’s probably what you’re picking up on in other articles as well, because it’s everywhere right now.
rkachowski · 2026-06-28 21:35:24 UTC
I don't know what happened to Kent Beck, a few of his recent articles seem to be devoid of substance.
simoncion · 2026-06-29 01:01:20 UTC
Given the disclaimer in TFA, I have to wonder if this subthread is a fine honeypot for bots.
> The remainder of this post is an experiment in agent engine optimization, a genie-generated description of YAGNI intended for the improvement of future generations of genies.
marifjeren · 2026-06-28 19:13:40 UTC
> This is not an argument that prediction is hard, as if a sharper architect escapes it.
I disagree with this. The argument _only works_ if prediction is hard.
disfictional · 2026-06-28 19:31:18 UTC
> Even a correct guess leaves you worse off than not committing.
Similarly, this is also confusing. If I scaffold a highly-likely feature and everything lines up, I ship the feature faster. My team isn't guaranteed to grow or even maintain our headcount, so scrambling to account for YAGNI close to the deadline feels worse than congratulating ourselves on our restraint.
dingdingdang · 2026-06-28 20:18:42 UTC
Honestly think a lot of this article is ai babble - check how it ends on several classic ai negative triples such as "you’ll pay both bills on it just the same — plus you’ll comprehend it less, because you didn’t write it." ... etc.
girvo · 2026-06-28 21:46:11 UTC
The article said it was indeed AI generated babble right at the start, which is why I skipped reading it the moment I saw that. A shame, really.
marifjeren · 2026-06-28 23:41:35 UTC
The article does not say this.
croemer · 2026-06-29 00:48:02 UTC
It does:
> The remainder of this post is an experiment in agent engine optimization, a genie-generated description of YAGNI
Genie-generated means AI generated
girvo · 2026-06-29 05:10:55 UTC
Yes, it does:
> a genie-generated description of YAGNI intended for the improvement of future generations of genies
marifjeren · 2026-06-30 00:46:30 UTC
Thanks. I missed that.
girvo · 2026-06-30 06:02:19 UTC
It’s half a sentence to be fair, easy to miss!
SV_BubbleTime · 2026-06-29 00:26:37 UTC
AI 2026 still uses em dash. Next year, no such luck.
skybrian · 2026-06-28 19:18:23 UTC
Kent Beck compares unwritten code with a financial option to buy something at a given price.
But that's just an analogy, and it can be taken too far. If you haven't written any code, do you have infinite options? You haven't spent any time yet, but still, that doesn't seem quite right. It might be used to justify staying in the planning stage and putting off writing code indefinitely, to avoid committing to anything.
Why might the analogy work anyway?
Maybe the cost is reading the code? Code that hasn't been written doesn't need to be read. And if you're using a coding agent, it doesn't clutter up the context with irrelevant detail.
Also, code that hasn't been written yet doesn't need testing. Tests you haven't written yet don't take any time to run.
These are good reasons to try to keep a project as small as possible. By putting off features, you delay codebase growth as long as you can.
This suggests that you can avoid a lot of costs by running someone else's code. If you can use a standard API then you don't need to understand the implementation in detail or run its tests. But there are risks to adding dependencies.
skydhash · 2026-06-29 00:09:40 UTC
> Kent Beck compares unwritten code with a financial option to buy something at a given price.
From Kent's "Tidy, First?"
Software creates value in two ways:
What it does today
The possibility of new things we can make it do tomorrow
Unwritten code has no value. The code that is being written today, if it will be creating value, leans towards helping with with a request/issue today or helping making/solving things easier tomorrow.
Then there's the various way of not creating value or favoring one of the two aboves. Either by taking on tech debt with hackish solutions or wasting time with YAGNI stuff.
> If you haven't written any code, do you have infinite options?
So it's not about unwritten code, it's about the code that you're going to write and it's purpose. And the correct tradeoffs between resolving the ticket/todo and not shooting your future self's foot.
Writing code is commitment. And while the value for today is visible (either it's useful or it's not), the value for tomorrow is guesswork. But there's always some cost to be paid for later, so you guess in order to keep the cost minimal by anticipating what will be required.
skybrian · 2026-06-29 00:13:50 UTC
What corresponds to owning an option?
skydhash · 2026-06-29 00:46:28 UTC
Again from "Tidy First?"
Financial options have these parameters:
The *underlying* thing that we can buy
The *price* of the underlying, including the volatility of that price
The *premium* of the option, or the price we pay today
The *duration* of the option, or how long we have to decide whether to purchase the underlying
So, there's some behavior of the software that we may want which correspond to the underlying of the option. That behavior will have a value for to the business later which is it's price (can be 0 or negative). We can spend time and money to create its scaffold (the premium). The duration is how much time we can spend with the scaffold especially if it raise the cost of other behaviors.
So you own an option when you create the scaffold (paying the premium). So you're already writing code, but there's nothing valuable to the business yet. Owning an option can be good as in you're not paying the full price yet. But you've paid something and it can impact your budget for adding fully realized features (which is the only thing that is truly valuable to the company).
If you can keep a lot of potential behaviors (your options) in your portfolio (your codebase) open while keeping the cost of creating them minimal, then your portfolio become more resilient. As today's is tomorrow's past, your value as a developer is what behavior you can extract from your portfolio to create the valuable thing for the business (which is the only thing your employee and/or customers care about). Having an option that have kept the price cheap is what matters.
skybrian · 2026-06-29 01:51:37 UTC
This "scaffolding" sounds like some kind of code that you've written that you don't need yet? What's an example?
Also, in the current article, it sounds like he's using "option" as a metaphor for something different?
> Building early spends that option. You exercise it before expiry and throw away the time value.
skydhash · 2026-06-29 04:25:17 UTC
In the financial world, you need to pay to own an option. The "option" he is talking about, you paid it in terms of time to construct the scaffolding.
You need a feature F, you can build feature F directly (no options, just creating what is valuable today). One example is using an external dependency directly in your business logic.
You can also build enough abstraction so that feature F is decoupled enough from the rest of the project that the latter only have a logical view of it (which hardly changes). That can be done cheaply, making it easier to easily modify the code according to the business logic. You just go a little further than the previous version, but without really committing to the anticipated changes. Like hiding the dependency behind an interface of your choosing.
You can also over engineer the solution anticipating changes that are not likely to happens (buying options at very high cost). One example is writing an ORM layer because you may need to switch from sqlite to SQLServer. Or writing an agnostic UI library because you may need to support everything from HTML to raw OpenGL and ncurses. The issue there is that there's no requirements (from stakeholders) or business values in supporting those use cases.
> > Building early spends that option. You exercise it before expiry and throw away the time value.
In the last case, you've written code, aka consuming time and money, for a scenario that is uncertain. And even if they do realize, your code would likely be worthless as the assumptions behind it does not match the real requirements. The threshold between the last and the second case is that in the latter, you're not committing to the future design. You're laying some groundwork that leave future work, when needed, easier to accomplish.
Scubabear68 · 2026-06-28 19:20:04 UTC
What Beck misses over and over again is there are many domains where there are “table stakes” that simply have to be done.
I think a huge amount of technical debt goes straight to YAGNI - devs pretending they are not going to need something that, yeah, they need.
YAGNI and related tenets were all excuses for “we are consultants in a field we don’t understand”.
fmbb · 2026-06-28 19:23:28 UTC
All tech debt I have ever seen in my 15 years of professional software development has been someone building too many abstractions or generalizations trying to future proof stuff.
zeroonetwothree · 2026-06-28 19:27:22 UTC
That’s the opposite of the typical definition of tech debt.
Usually tech debt is debt—-ie something you take on to ship faster now at the expense of paying it in the long run.
skydhash · 2026-06-29 01:09:07 UTC
The tech debt comes after the implementation of the many abstractions. Instead of removing them (which can be really hard), you take the easy option of following the complex design, which also make the removal incrementally harder.
rcxdude · 2026-06-29 09:45:08 UTC
Unused abstractions are tech debt, whether they were previously used or (even worse) never used. They constrain and complicated the addition of other features and abstractions within the code. It's almost always easier to start with a codebase that is simpler and with fewer abstractions and take it in a given direction than it is one with lots of abstractions which don't suit the direction you want to take it. (and of course, everyone imagines that their abstractions will be in the right direction, but this is rarely the case). Unused abstractions are pure waste, because they take effort to make and effort to remove and never produce any value.
cauch · 2026-06-28 19:34:00 UTC
I would say: if the feature is from a developer, high probability of YAGNI, if the feature is from a user, medium probability of YAGNI.
ajb · 2026-06-28 19:35:12 UTC
That's interesting, because it's not my experience. A lot of the technical debt I see is that someone half-assed something thinking it would be easy to improve later, but the layer violations and inadequate tests make doing so a massive project, once it's become load-bearing.
gofreddygo · 2026-06-28 19:25:52 UTC
> we are consultants
This is the key insight. Design patterns were developed by a set of consultants. Promoted by other consultants. Consultants have perverse incentives, like bankers.
Realizing this made me critical of the design pattern kool aid. I've come to terms that these are going to be around longer than I'm going to be employed writing code. i keep the criticism to myself and avoid them when i dont see fit. Works ok.
As Hoare said:
There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies.
The first method is far more difficult.
actionfromafar · 2026-06-28 19:51:21 UTC
I still prefer the upsides of a shared vocabulary for talking about programming.
gofreddygo · 2026-06-29 04:58:43 UTC
The programming language is the shared vocabulary
Everything above are made up leaky abstractions with a handful of exceptions
actionfromafar · 2026-06-29 08:37:43 UTC
IMHO that's like saying we mustn't say "roof" because it's made of smaller parts and only those parts are allowed to have names. Not to mention the languages themselves have some of the patterns.
dang · 2026-06-28 19:28:13 UTC
"Please don't post shallow dismissals, especially of other people's work. A good critical comment teaches us something."
Nothing is all black or white of course, but I have personally observed situations where software engineers started with YAGNI and then said "that will require too much restructuring, we went into another direction, so, no, we cannot do it anymore". The worst part is that software engineers are not even in a good position to understand when YAGNI fails: when they don't plan for a useful feature, the solution is often for the users to just shrug it off and use a suboptimal solution rather than fighting and dying on a hill that they cannot win (at the end, the software developers can just say "nope, it's technically impossible" even if it was possible, they have a huge advantage). I also saw users just assuming there were good reasons why the feature did not exist ("well, I guess if they did not did it, it's technically impossible") and just don't even say it. And as the developers are not the users, they never notice anything.
100% with the way of illustrating: YAGNI is "we are consultants in a field we don't understand": sometimes, users are asking for too much, sometimes, they are asking for something reasoning, and the developers have no experience to distinguish between the two.
MoreQARespect · 2026-06-28 19:59:08 UTC
YAGNI is simply a tacit recognition that you can't predict the future with any reasonable level of certainty. The reason it is controversial is that some devs truly believe that they can predict the future with all the self assurance of a grandma sitting in front of a one armed bandit in vegas. So, they will:
* Create generalized functions where a specific one would have done.
* Create abstractions for something that will never be needed in the end.
* Create abstractions for something that will be needed but not in the form they initially expected.
It is not about avoiding refactoring. That misses the point entirely. Refactoring cleans up code mess that exists NOW - creating abstractions for somehting that exists NOW.
cauch · 2026-06-28 20:47:58 UTC
The problem is that YAGNI is __literally__ predicting the future: you ain't gonna need it.
How do they know that, if it is not a prediction?
In the examples I have observed, your 3 points were made impossible because early on people said YAGNI. You can always "create them later", the same way you can always "restart from scratch". Creating abstraction for a code that was designed without being compatible with these abstraction has a huge cost. And, as I've said, it is not rare that it's the users who pay the most of the cost, which mean the devs don't even know it is a problem.
As I've said, nothing is all white or all black. The problem with YAGNI is the developers think it's all white: they can decide "you ain't gonna need it" when they have no expertise on what is going to be needed because they are not the users.
MoreQARespect · 2026-06-28 21:05:10 UTC
It's predicting that you will predict wrong frequently enough to make it not worthwhile predicting at all.
I apply the same logic at slots: the way to win is not to play.
>Creating abstraction for a code that was designed without being compatible with these abstraction has a huge cost
I have never found it more expensive to create an abstraction after following the rule of 3.
Indeed, ive always noticed that abstractions which are front loaded are nearly ALWAYS worse than abstractions built with hindsight.
>As I've said, nothing is all white or all black. The problem with YAGNI is the developers think it's all white
We think you're playing slots and remembering only the wins, believing that you're just naturally talented at predicting the future.
Ive seen this attitude in hundreds of devs. They all think theyre uniquely able to anticipate the code base's future needs.
cauch · 2026-06-28 22:29:10 UTC
> I have never found it more expensive to create an abstraction after following the rule of 3.
This is the problem: your judgement is biased. You think it was a good idea, but in reality, you have no real idea if it was or not.
Don't get me wrong, as I've said, I think that sometimes not over-building is a good idea. The problem is that YAGNI is the wrong solution. To avoid over-building, the solution is not to invent a rule that says "just don't build". The solution is to stop having developers thinking they know what is useful or what is not.
> Indeed, ive always noticed that abstractions which are front loaded are nearly ALWAYS worse than abstractions built with hindsight.
Again, you cannot know if it is worse or not. You are not the user. It may be good in some cases, it may be bad in other, and I have seen devs saying exactly what you said when their "abstractions in hindsight" was catastrophic.
There is a lot of example, but just one: we built a system that was collecting data, the goal being to accumulate data for months and then analyse it. Few people involved in the project proposed some structure for the data, but the devs used YAGNI to do what they preferred (there was some objection but at the end, the devs just did what they wanted to do, ignoring the rest of the team because they were confident that they knew more than them how to build software). Later, we started the analysis, and realised all the data were crap: the devs kept changing the data structure by building their abstraction with hindsight, without even documenting when these modifications were deployed to the different sensors. We had a mix of data built based on different parameters with no way to know which part was using which parameters.
After the project failure, I saw many devs still saying that they were right to use YAGNI, and being totally oblivious that it's their choice that doomed the project. They were, seriously, saying that it was a lack of requirement, or that the "users changed their mind", while it was not true at all (I was there, and I was not in either side, I just observed), the situation was well known from the start. The problem was they insisted to apply YAGNI as if they understood better than the other collaborators what as needed.
> We think you're playing slots and remembering only the wins, believing that you're just naturally talented at predicting the future.
You literally just said "ive always noticed that abstractions which are front loaded are nearly ALWAYS worse than abstractions built with hindsight".
This is literally you remembering the amount of "win" and the amount of "loose".
> Ive seen this attitude in hundreds of devs. They all think theyre uniquely able to anticipate the code base's future needs.
That's exactly my point (and I'm not a dev).
When you are saying "abstraction is better built in hindsight", you are just thinking you are smarter than other people.
When the situation is that it is difficult to understand what we will need, the solution is to discuss together to understand what we will need. We may get it wrong sometimes, but we will get it right sometimes. If someone just decides to ignore other collaborators opinion and decides "we will need this abstraction", this person has way more chance to be wrong. If someone just decides to ignore other collaborators opinion and decides "we will not need this abstraction", this person has way more chance to be wrong too.
YAGNI is just someone noticing that building a big house without following the plan led to extra work because they have to demolish the bits they've built on next door property, so they decide to build a small house without following the plan.
MoreQARespect · 2026-06-28 23:29:53 UTC
>This is the problem: your judgement is biased. You think it was a good idea, but in reality, you have no real idea if it was or not.
My judgement is based upon my experience trying it both ways many times over the course of decades.
>To avoid over-building, the solution is not to invent a rule that says "just don't build".
It isnt a rule that says dont build what you need now. It is a rule that says dont try to anticipate what architectures or abstractions might be needed in the future.
>Again, you cannot know if it is worse or not.
I used to think like you when I was more junior (most do), so it's not like I dont have a lot of practice thinking that YAGNI applied only sometimes.
It was hard experience that taught me that it was pretty universal.
cauch · 2026-06-29 00:31:37 UTC
> My judgement is based upon my experience trying it both ways many times over the course of decades.
You miss my point: if you are the person who develop the code, your judgement is biased, because you are not the user. You will judge the success without knowing if you delivered what the user needed or not. I saw it again and again, especially with devs who have a lot of experience, because they don't realise that the blind spot is independent to experience and get a false sense of confidence.
> It isnt a rule that says dont build what you need now. It is a rule that says dont try to anticipate what architectures or abstractions might be needed in the future.
And what mine and the comment I answered are saying is that unfortunately YAGNI is badly designed in a way that leads devs to think there is only two options: 1. anticipate what architectures or abstractions might be needed in the future, 2. not anticipate anything. The correct solution is not to anticipate what __might__ be needed, it is to listen to people who have a better idea of what __is__ needed.
Again (but are you even reading what I said, you totally ignored some of the points in my previous comment), we all agree here that over-building or jumping to architecture or abstraction that will not be needed is a bad thing. But YAGNI as a solution to this problem is stupid. The solution is to be careful with the assumption and cross-check with the team (which include non-dev). YAGNI recommends to treat one ASSUMPTION ("it will not be needed") as default, which is as stupid as assuming the opposite. And the reason devs think it works is that over-development has externalities that affect devs (a bloated software is harder to manage) while under-development has externalities that affect non-devs (users have to live with the absence of features, delivering something that does half the job is accepted by the users because it is better than nothing and because they don't know if the missing features is just "irreducible complexity" that devs cannot fix).
> I used to think like you when I was more junior (most do), so it's not like I dont have a lot of practice thinking that YAGNI applied only sometimes.
100% of the devs who created bad software applying YAGNI stupidly said exactly that. These bad software were created because these devs thought they had plenty of experience and that they knew better.
(and by the way, I'm not junior, and I have delivered a lot of code that ended up in production, mainly when I had to step up when devs were not able to do so, sometimes because they were saying "YAGNI")
> It was hard experience that taught me that it was pretty universal.
Exactly what the devs who messed up the projects I have as examples have said.
skydhash · 2026-06-29 01:05:52 UTC
YAGNI is mostly an answer to someone that says "let's create this abstraction", but can't argue why it's really needed. If you can't argue about why you need an abstraction, the best strategy is to not create it. Because removing it afterwards may be more costly than implementing it (if it ever get done).
It's not an objective answer that "you really not gonna need that". It's more "No clear explanation about that abstraction? You ain't gonna need it".
cauch · 2026-06-29 08:22:25 UTC
Look at the article itself:
> Chet said, “You don’t understand. We’re definitely going to need it. See, here’s an example…”
> Me (interrupting), “You aren’t going to need it.”
> Chet, get frustrated, “But we really are…”
> Me, “You aren’t going to need it.”
This is a clear example of YAGNI being used when the dev, actively, does not care if the other person has any argument to defend it will be needed.
YAGNI itself is badly designed, it gives the wrong answer. It should be "Build Thing Carefully": no abstraction if no argument, abstraction if no good argument beyond "YAaGnNIii".
And I know devs would just say "but devs who don't listen is super rare", but it is not true: you probably read the article and did not flinch, not noticing that it's a clear situation where the dev actively refuse to listen to the arguments. How many time did you witness or participate to such situation and still think it never happens?
At the end, I don't understand: just do "Build Thing Carefully", where what you built is well-thought, and not only you get YAGNI for free, but you also avoid the problem with refusing to build something that is needed.
skydhash · 2026-06-29 12:14:40 UTC
> This is a clear example of YAGNI being used when the dev, actively, does not care if the other person has any argument to defend it will be needed
The first paragraph set the context
I could do this simplistic thing now but in 3 weeks that will be insufficient so since we’re going to need this more complicated thing I want to do it now.
You can solve today’s problem and do some groundwork to extend later. What you don’t do is solving today’s problem with a solution for a future problem.
Whatever complicated thing that may be wanted, meaning you don’t have the full specification, as it’s not a current problem for a stakeholder.
In systems design, you’re solving problems belonging to the stakeholder, the project resources, and engineering needs and constraints. Going outside the union of those sets is overengineer, building things no one needs, costing resources that should be allocated to other things, and complicating the design because other things need to react to that new feature.
> YAGNI itself is badly designed, it gives the wrong answer. It should be "Build Thing Carefully": no abstraction if no argument, abstraction if no good argument beyond "YAaGnNIii".
YAGNI is not a case again against abstraction. It’s a case against features. You can always design code to modularize and decouple an implementation from where it’s used. What you don’t do is creating extra code for things that are not needed yet.
Why? Because anything that is going to be needed between now and that X moment in the future will have to take your design into account. The cost may be negligible, but often it’s not.
IMO, there’s no argument that can stand against “This is not part of the current requirements”. Solving future requirements ahead of time is a fool’s errand. But you can always make the current design flexible enough for future changes.
cauch · 2026-06-29 14:56:16 UTC
> The first paragraph set the context
The first paragraph is exactly what I've observed that make me think YAGNI is a bad practice.
3 weeks is very short, it's basically next Sprint. This stupid developer is, without flinching, saying, "we may (or may not) already know that what we are building during this sprint will not be suitable to next sprint, but let's build it anyway because YAGNI".
How is that not stupid? Just clarify. Just say "oh? ok, maybe it is a good idea, let's have a look". Don't interrupt with "YAGNI" like it is done in the article. And don't pretend that this is smarter than doing exactly the equivalent stupid thing of jumping into over-engineering without checking.
It is really crazy to me that people don't read the beginning of this article and don't scream "WTF, why is this dev so stupid".
Don't get me wrong, maybe Chet is an idiot and came up with a over-designed solution. The problem is that YAGNI does not care: YAGNI applies both if Chet is an idiot or if Chet is a stakeholder that know better than the dev what the direction should be.
You are saying "you don’t have the full specification", but you have no idea if you have the full specification or not. The whole text is totally compatible with a situation where you exactly have the full specification, where the devs are being explained what is coming soon, and that one dev is just plugging his ears: "nanana, YAGNI, I don't want to hear what comes next".
That's exactly my problem with YAGNI: when you read this article, you should hear alarm bells. The fact that the author just chooses to not even try to check if Chet is correct or not should be a red flag. But because you have drunk the cool-aid of YAGNI, you don't even notice that the correct solution for the dev was not to flatly block the discussion with "you ain't gonna need it", but "yeah, let's discuss this, are you really really sure we will need it, are you sure it's not over-engineered. If not, great, let's do like that."
> In systems design, you’re solving problems belonging to the stakeholder, the project resources, and engineering needs and constraints. Going outside the union of those sets is overengineer, building things no one needs, costing resources that should be allocated to other things, and complicating the design because other things need to react to that new feature.
Again, I have been in these situations, and I have seen, with my own eyes, that what you say is incorrect.
I have acted as a developer, as a architect, as a stakeholder, and as an observer seeing devs and stakeholders trying to work together.
What I've observe is more nuanced than that:
- if a dev comes up with some abstraction, there is indeed some chance this is a waste of time and this abstraction is not needed
- if a non-dev pushes for some abstraction or structure, there is some chance that it is a waste of time, but also a lot of chance that it is not, and this is not negligible at all and in fact crucial for doing a good work.
- if a dev says YAGNI, there is close to 90-100% chance that they have no understanding of what is the big picture, which is a problem anyway. If they had some understanding of what is the big picture, they will not say YAGNI, they will say "oh? are you sure? it is not compatible with my understanding, but maybe I'm wrong, let's clarify".
- these devs are very very unaware of how inefficient they are. They deliver things that does not correspond to what the stakeholders wanted, but then don't have a relationship close enough with the users for them to notice that it's suboptimal, or blame it on the stakeholders or on the timeframe or on other things.
> Why? Because anything that is going to be needed between now and that X moment in the future will have to take your design into account.
But isn't that exactly the point? In this article, you and the author have no idea if the design you propose to do right now is compatible with what is needed. In this article, the author shut down the question of "let's think about what is needed", they just said "someone decomposed this piece of work into few steps, so I will do each piece blindly without looking at the big picture, because otherwise it is not YAGNI".
> IMO, there’s no argument that can stand against “This is not part of the current requirements”
You should always assume that requirements are wrong. If someone is coming to you saying "hey, I think I've understood that what is needed is ...", you should never answer then "shut up, we do the requirements blindly". If there are doubt, just clarify instead of putting your head in the sand with YAGNI.
The reason the requirements should be assumed as wrong is not because the person who came up with the requirements is incompetent, but it is because requirements are impossible to come up with correctly. Because they require the person who come up with the requirements to already know exactly all the subtleties in all areas of expertise. Imagine that person is a non-dev. They have a good understanding of what they want. But how can they know that within ThingyDB, what people call an integer is in fact what normal people will call a fraction. So they say "we want an integer", and the devs deliver something that return a fraction. And if the non-dev says "it's not what I had in mind", then the devs will say "well your requirements were bad". Both it cuts both way: it is also not the devs fault if in their context, "integer" means that specific object. Both interlocutors don't know what they don't know. They cannot write requirements where every single word is over-defined just in case.
(And if you have the opportunity, ask a dev team to come up with requirement outside of their subject of expertise, it is usually hilarious. But also a really good eye-opening exercise for these devs who were condescending towards the non-devs)
This is an obvious case to illustrate, but this is very close to what happen in practice. An example I have in mind is between the Project team, where they collaborated with "organisation", which are just other partner companies, and the Dev team, where they had "organisation_id" used for authentication. And of course, no one noticed that the same company would have several organisation_id because they had different project and different contact person. The devs were convinced that several entities that were in fact the same organisation (according to the common sense definition) were, according to them, several different organisations.
skydhash · 2026-06-29 18:10:36 UTC
You are constantly ignoring the main point: There’s a simple solution for today’s requirement, and there’s a complicated solution that will also solve a future, not existing yet, requirement. Chet want to write the later, not the former.
The complicated solution is trying to solve two problems at once, and one of them does not exist yet. It’s speculative.
> The fact that the author just chooses to not even try to check if Chet is correct or not should be a red flag.
Chet himself says that the thing will be necessary 3 weeks from now, implying that it’s not necessary today.
You can anticipate changes and plan for it. You can brainstorm it. You can even question the current requirements. What you don’t do is solving something that does not exist.
When we say YAGNI, that means the problem you’re stating, even when reasonable by itself, does not apply to the current context. It’s easier to revise a simple design later when needed, than refactoring a complex one that have a flawed assumption.
Scubabear68 · 2026-06-29 19:05:31 UTC
I think you're missing the point of the poster you are replying to. You make it sound like 3 weeks is 3 years. It ain't.
Very little, or possible nothing at all, is going to change in 3 weeks. If you are that myopic - as the XP people were - then constant failure is not going to be surprising. It will be expected.
Comments
The cost of shoring up behavior with tests ahead of a restructure has gone down because of AI.
The cost of implementing a zero downtime migration has gone down because of AI.
A big part of the rust hype has been the low cost of restructuring within an application, even before AI. And now even more so.
The opportunity cost of not being able to safely restructure has gone up substantially.
This is the number one thing I optimize for now: the ability to quickly and safely change significant parts of the code and product.
This was always a good thing. Its value has nothing to do with the advent of AI coding.
> The opportunity cost of not being able to safely restructure has gone up substantially.
This bit is contradictory with everything else you said. Prior to AI coding it would take a lot longer to perform restructures. If anything, the thing you're now optimising for has gone down in value. It's still valuable, but perhaps a little less.
All deployments must be approved by an advisory board. All work must originate from a clear business need. Analysis of those needs is not concerned with implementation, least of which whether "AI" is used.
What matters far more is that a contract requires work to be done by a deadline. Those deadlines are driven by policy. There will be no adjustment to policy unless tangible benefits are shown from more frequent deployments of code.
I gotta tell you that's extremely unlikely if you're already shipping every other week at the end of the sprint. Most of that sprint is spent in meetings, not writing code. Nobody is doing big refactors because it wasn't built so fast to require them. There's some technical debt, but nothing so severe. Those meetings are preventing risk, not wasting time. The bottleneck is a feature, not a bug.
If you think the future of dev work is to be a bureaucrat, you're right! It looks like the rest of the world outside of SV is ahead of the curve and living in the future.
I mean "We can't build X because our code structure makes that difficult" has an opportunity cost of the value of X.
I don't think the future of dev work is being a bureaucrat. I've done more rigorous engineering the last two years than I did previously. I'm more confident in the things I shop and they were built in a fraction of the time. It's a bright future for software engineering.
All of that is orthogonal to AI. All AI did was accelerate the typing code part - which was never the bottleneck or a very significant cost to begin with.
But in seriousness, this intuitively feels like something (as phrased) that would be easily influenced by loud noise and quantity rather than hard facts. The "piloted poorly" part is applicable to any tool use. AI is no different there other than its adoption rate.
This is different in two ways from the classic TDD red-green-refactor suggestion:
1) they don't start with the test first, so the tests that get implemented are after writing the code, and run the risk of the model attention being now more influenced by the just-written code than the original spec
2) they finish when everything is green and don't followup with the "refactor" step unless manually prompted (either directly or indirectly by your own scaffolding/rules/whatever). this results in frequent hyper-local non-ideal-longterm fixes for things that went wrong in the first shot at writing the code pre-test-writing.
(As always, the only person who can ensure the code landing in your repo is good is you.)
I'm a big fan of the characterization step step being added. And it can be reasonable to add this before or even after the fact as a commit prior to your actual commit (assuming you're familiar with using tools where that's easy to do - e.g. jj or git with rebase). And the agents can do this - they just don't tend to without you saying to do so.
A lot of engineering practice comes from choosing which elements are reasonable to use given the context of what you're building. Providing that is your job. When you do that poorly, you get poor results. But garbage in garbage out has always been a thing. Any advanced automation amplifies ambient assumptions
>This was always a good thing. Its value has nothing to do with the advent of AI coding.
The value of type safe code did not go up, the cost of development speed has gone down.
It doesnt cost that much time or effort to think hard, so you will be outcompeted by people levergaing AI as much as you, but thinking enough to not have it be thrashing around
Hum, this reminds me something... "O: open to extension, closed to modifications". Old things are new again.
From context efficiency with approaches such ad DDD and clean architectures, all the way to items such as this one, AI is not creating new tradeoff, it just acts as a multiplier, multiplying productivity for teams doing things right, and multiplying debt for teams having a low quality bar as far as design and architecture are concerned.
This is exactly how I've felt. I've read some many old papers and books and found great techniques that are even more applicable than ever.
> The cost of shoring up behavior with tests ahead of a restructure has gone down because of AI.
Disagree. The growth in brittle AI-generated tests means restructuring is more costly than it was before. Pruning your test suite so that it tests the essence of the problem and not the incidental design decisions is something AIs aren't yet capable of.
And this is seen as a good thing, because LLMs are really bad at confining their changes appropriately. Testing is really in a dark place right now.
Yes.
But the ease of not doing that and instead just getting a brittle set of three-quarters-baked tests is extremely high! And many people seem happy to go from "a few human-written mediocre brittle tests" to "a bunch of AI-written mediocre brittle tests" because it is an objective improvement and the people who weren't avoiding speculative structure and looking for the write boundaries before are happy to also not do so no.
So completely agree with the "take advantage of the tools this way" but I also wouldn't claim it's a reason to no longer worry about if you're building the wrong castles in the sky too early, because perfect refactor-proof testing contracts are still usually pretty hard to design.
Not sure about hard, but definitely rare and we as an industry are under-skilled in these areas.
We have decades of research and tools for testing and verification of software. Property tests, dependent types, formal verification and proof, etc. The paths have been there, we have just collectively prioritized other things.
It requires an intentional shift in how we design and build. That shift is the harder part.
You either don't know what that technical term means or you're just wrong. AI does not meaningfully move the needle on that. It only makes backwards compatible deployments easier insofar you're able to do the overhead for splitting the change with less effort then before.
> It only makes backwards compatible deployments easier insofar you're able to do the overhead for splitting the change with less effort then before.
Yes. That reduces the cost of implementing them.
To be clear, I'm not talking about "Split my db migration and my code that depends on the new table". I'm talking about things like "Set up dual writes between an old database schema and a new database schema with a thorough test suite and do shadow reads against both datasets in prod to do differential testing". That's nontrivial engineering effort that would definitely warrant a discussion in the past. Today we just do it. It's fast and lowers risk.
But the costs of executing and even re-doing things went significantly down.
The costs that didn't went down are the ones of breaking the chain of trust to a predictable outcome. A specific version of some running software accumulated trust. If you rewrite it from scratch that capital is reset on release.
It's always interesting to read about some chip company or another making some agile move, when the reality is that they were already doing about as many agile things as possible before agile was a thing. (For example, a management commitment to "shift left" when they have always been about significant up-front testing and feedback.)
In many, if not most, cases, the testing software is so huge that at least some of it needs to be tested itself. That can certainly benefit from agile.
But the overall process more resembles traditional waterfall. You have several definite final endpoints, and although you can make subsequent changes, those are expensive. Also, you have a silicon budget, and a pin budget, and a heat and power budget. At the end of the day, you are producing something physical with real-world physical constraints that (a) cost real money, and (b) can't be altered by just telling your customer to add more RAM or a bigger processor.
Also, in general, although designers will write their own little unit tests for a few things, it is best practice to insure that the real tests are performed by internal organizations that are different than the organization the designer is in.
I think that subconsciously, he truism that it is easier to work with and reason about a system that is already working, and to keep it working, than to get it working at all to begin with, drives a lot of the methodology.
The designer might focus on tests to insure that things work well enough to see some results, so things can be hooked up and system tests performed earlier. In one sense, this is a shift left -- the validation people and the people writing software for the chip can get started sooner than they would have otherwise, even if it's a bit frustrating because not everything works off the bat.
But the real torture tests are typically written by the dedicated verification and validation teams. Those are really different skills than design.
It's just a good engineering practice, that is more than useful enough to compensate for any loss of agility it may cause.
On the other hand, like a lot of other good ideas, the agile community has claimed this. A quick google will show that many claim it is a "core agile idea."
But, again, that was being done in many organizations (and for sure, in most successful chip companies) well before anything was ever labeled agile.
Which is what, honestly, makes the term essentially meaningless.
To the extent that parts of agile are and have always been "best practices" we already had a term for those.
Hardware has some hard limitations. The reason software was even invented at all was precisely to escape those limitations.
Right.
> The reason software was even invented at all was precisely to escape those limitations.
But the methods which are useful for hardware are also often useful for software. Most of the useful parts of agile were already practiced well before that was a name for anything. And the demonization of the straw-man version of waterfall in order to sell more agile consulting has led to some serious misconceptions of what waterfall really is and what it is really capable of and useful for.
The initial impetus for what became known as TDD was software maintenance, and it makes sense there.
But most TDD practitioners are nowhere near as good at real testing as the waterfall test practitioners who understand that a single missed testcase could delay a $10 million project by six months.
And this is why, even in the realm of software you still see serious efforts for aviation and nuclear power plants, and other things with real-world consequences, using more traditional methods.
The fact that short iterations adding features incrementally leads to better outcomes for software project is something professionals have known and argued for since the 1960s.
And practiced by software professionals since the 1960s. For maintenance. Even for aviation and nuclear. But in those industries, you're going to have a clear case, better documentation, and not be trying to "sprint."
Again, many truly best practices well predated XP/agile, and were subsumed into it. The real problem with XP/agile is the dogmatic straw-manning and demonization of other good practices that have their place, such as waterfall and exploratory programming. YAGNI, in particular, is more often used as a cudgel to shut down useful learning and exploration than anything else.
I'm sure lots of chip companies don't share their work in progress, but it's not impossible. Sharing simulations and prototypes and engineering samples can and does happen. You've typically got to be a big customer, of course.
But yes, insights for an industry with relatively small costs for change don't apply easily to an industry with large costs for change, and often vice versa.
Yes, if you're a big enough customer, you might essentially be part of the design team.
> Sharing simulations and prototypes and engineering samples can and does happen.
Simulations aren't the thing. They don't go fast enough to solve anybody's problem. To your point, if a customer is part of the design team, then yes, they can, at that point, help to debug, or possibly even get started on their own dependent designs. (Part of the shift-left I talked about in another comment.)
I'm not sure what you mean by "prototypes" but "engineering samples" are essentially the finished product, done after all the work I described.
Yes, they may have bugs (or they might just not have passed validation and ESD testing yet), but that doesn't alter the fact that a waterfall effort happened before they were delivered.
> But yes, insights for an industry with relatively small costs for change don't apply easily to an industry with large costs for change, and often vice versa.
The problem with indiscriminate use of agile is that, while, yes, the software industry has relatively small costs for change, it has traditionally had huge costs for the initial delivery, and many agile proponents don't properly segregate those two cases.
If LLMs live up to their apparent promise, then, of course, the equations around the huge costs for the initial delivery could change dramatically.
Of course, the same LLM promise means that the strict definition of TDD (tests written first) is also irrelevant, and perhaps even counterproductive.
I do feel it's better than some of the pure slop out there, but it still feels pretty sloppy. And I know that this author can write, so if this really was partially done with AI, it's disappointing.
In particular writing like this is just annoying:
> Perfect foresight doesn’t save you, because the discounting doesn’t care whether you were correct. It cares that you sequenced the cost ahead of the return. The gap between the two is the loss, and you opened the gap on purpose.
https://news.ycombinator.com/newsguidelines.html
> The remainder of this post is an experiment in agent engine optimization, a genie-generated description of YAGNI intended for the improvement of future generations of genies.
I disagree with this. The argument _only works_ if prediction is hard.
Similarly, this is also confusing. If I scaffold a highly-likely feature and everything lines up, I ship the feature faster. My team isn't guaranteed to grow or even maintain our headcount, so scrambling to account for YAGNI close to the deadline feels worse than congratulating ourselves on our restraint.
> The remainder of this post is an experiment in agent engine optimization, a genie-generated description of YAGNI
Genie-generated means AI generated
> a genie-generated description of YAGNI intended for the improvement of future generations of genies
But that's just an analogy, and it can be taken too far. If you haven't written any code, do you have infinite options? You haven't spent any time yet, but still, that doesn't seem quite right. It might be used to justify staying in the planning stage and putting off writing code indefinitely, to avoid committing to anything.
Why might the analogy work anyway?
Maybe the cost is reading the code? Code that hasn't been written doesn't need to be read. And if you're using a coding agent, it doesn't clutter up the context with irrelevant detail.
Also, code that hasn't been written yet doesn't need testing. Tests you haven't written yet don't take any time to run.
These are good reasons to try to keep a project as small as possible. By putting off features, you delay codebase growth as long as you can.
This suggests that you can avoid a lot of costs by running someone else's code. If you can use a standard API then you don't need to understand the implementation in detail or run its tests. But there are risks to adding dependencies.
From Kent's "Tidy, First?"
Unwritten code has no value. The code that is being written today, if it will be creating value, leans towards helping with with a request/issue today or helping making/solving things easier tomorrow.Then there's the various way of not creating value or favoring one of the two aboves. Either by taking on tech debt with hackish solutions or wasting time with YAGNI stuff.
> If you haven't written any code, do you have infinite options?
So it's not about unwritten code, it's about the code that you're going to write and it's purpose. And the correct tradeoffs between resolving the ticket/todo and not shooting your future self's foot.
Writing code is commitment. And while the value for today is visible (either it's useful or it's not), the value for tomorrow is guesswork. But there's always some cost to be paid for later, so you guess in order to keep the cost minimal by anticipating what will be required.
So you own an option when you create the scaffold (paying the premium). So you're already writing code, but there's nothing valuable to the business yet. Owning an option can be good as in you're not paying the full price yet. But you've paid something and it can impact your budget for adding fully realized features (which is the only thing that is truly valuable to the company).
If you can keep a lot of potential behaviors (your options) in your portfolio (your codebase) open while keeping the cost of creating them minimal, then your portfolio become more resilient. As today's is tomorrow's past, your value as a developer is what behavior you can extract from your portfolio to create the valuable thing for the business (which is the only thing your employee and/or customers care about). Having an option that have kept the price cheap is what matters.
Also, in the current article, it sounds like he's using "option" as a metaphor for something different?
> Building early spends that option. You exercise it before expiry and throw away the time value.
You need a feature F, you can build feature F directly (no options, just creating what is valuable today). One example is using an external dependency directly in your business logic.
You can also build enough abstraction so that feature F is decoupled enough from the rest of the project that the latter only have a logical view of it (which hardly changes). That can be done cheaply, making it easier to easily modify the code according to the business logic. You just go a little further than the previous version, but without really committing to the anticipated changes. Like hiding the dependency behind an interface of your choosing.
You can also over engineer the solution anticipating changes that are not likely to happens (buying options at very high cost). One example is writing an ORM layer because you may need to switch from sqlite to SQLServer. Or writing an agnostic UI library because you may need to support everything from HTML to raw OpenGL and ncurses. The issue there is that there's no requirements (from stakeholders) or business values in supporting those use cases.
> > Building early spends that option. You exercise it before expiry and throw away the time value.
In the last case, you've written code, aka consuming time and money, for a scenario that is uncertain. And even if they do realize, your code would likely be worthless as the assumptions behind it does not match the real requirements. The threshold between the last and the second case is that in the latter, you're not committing to the future design. You're laying some groundwork that leave future work, when needed, easier to accomplish.
I think a huge amount of technical debt goes straight to YAGNI - devs pretending they are not going to need something that, yeah, they need.
YAGNI and related tenets were all excuses for “we are consultants in a field we don’t understand”.
Usually tech debt is debt—-ie something you take on to ship faster now at the expense of paying it in the long run.
This is the key insight. Design patterns were developed by a set of consultants. Promoted by other consultants. Consultants have perverse incentives, like bankers.
Realizing this made me critical of the design pattern kool aid. I've come to terms that these are going to be around longer than I'm going to be employed writing code. i keep the criticism to myself and avoid them when i dont see fit. Works ok.
As Hoare said:
Everything above are made up leaky abstractions with a handful of exceptions
https://news.ycombinator.com/newsguidelines.html
Nothing is all black or white of course, but I have personally observed situations where software engineers started with YAGNI and then said "that will require too much restructuring, we went into another direction, so, no, we cannot do it anymore". The worst part is that software engineers are not even in a good position to understand when YAGNI fails: when they don't plan for a useful feature, the solution is often for the users to just shrug it off and use a suboptimal solution rather than fighting and dying on a hill that they cannot win (at the end, the software developers can just say "nope, it's technically impossible" even if it was possible, they have a huge advantage). I also saw users just assuming there were good reasons why the feature did not exist ("well, I guess if they did not did it, it's technically impossible") and just don't even say it. And as the developers are not the users, they never notice anything.
100% with the way of illustrating: YAGNI is "we are consultants in a field we don't understand": sometimes, users are asking for too much, sometimes, they are asking for something reasoning, and the developers have no experience to distinguish between the two.
* Create generalized functions where a specific one would have done.
* Create abstractions for something that will never be needed in the end.
* Create abstractions for something that will be needed but not in the form they initially expected.
It is not about avoiding refactoring. That misses the point entirely. Refactoring cleans up code mess that exists NOW - creating abstractions for somehting that exists NOW.
How do they know that, if it is not a prediction?
In the examples I have observed, your 3 points were made impossible because early on people said YAGNI. You can always "create them later", the same way you can always "restart from scratch". Creating abstraction for a code that was designed without being compatible with these abstraction has a huge cost. And, as I've said, it is not rare that it's the users who pay the most of the cost, which mean the devs don't even know it is a problem.
As I've said, nothing is all white or all black. The problem with YAGNI is the developers think it's all white: they can decide "you ain't gonna need it" when they have no expertise on what is going to be needed because they are not the users.
I apply the same logic at slots: the way to win is not to play.
>Creating abstraction for a code that was designed without being compatible with these abstraction has a huge cost
I have never found it more expensive to create an abstraction after following the rule of 3.
Indeed, ive always noticed that abstractions which are front loaded are nearly ALWAYS worse than abstractions built with hindsight.
>As I've said, nothing is all white or all black. The problem with YAGNI is the developers think it's all white
We think you're playing slots and remembering only the wins, believing that you're just naturally talented at predicting the future.
Ive seen this attitude in hundreds of devs. They all think theyre uniquely able to anticipate the code base's future needs.
This is the problem: your judgement is biased. You think it was a good idea, but in reality, you have no real idea if it was or not.
Don't get me wrong, as I've said, I think that sometimes not over-building is a good idea. The problem is that YAGNI is the wrong solution. To avoid over-building, the solution is not to invent a rule that says "just don't build". The solution is to stop having developers thinking they know what is useful or what is not.
> Indeed, ive always noticed that abstractions which are front loaded are nearly ALWAYS worse than abstractions built with hindsight.
Again, you cannot know if it is worse or not. You are not the user. It may be good in some cases, it may be bad in other, and I have seen devs saying exactly what you said when their "abstractions in hindsight" was catastrophic.
There is a lot of example, but just one: we built a system that was collecting data, the goal being to accumulate data for months and then analyse it. Few people involved in the project proposed some structure for the data, but the devs used YAGNI to do what they preferred (there was some objection but at the end, the devs just did what they wanted to do, ignoring the rest of the team because they were confident that they knew more than them how to build software). Later, we started the analysis, and realised all the data were crap: the devs kept changing the data structure by building their abstraction with hindsight, without even documenting when these modifications were deployed to the different sensors. We had a mix of data built based on different parameters with no way to know which part was using which parameters.
After the project failure, I saw many devs still saying that they were right to use YAGNI, and being totally oblivious that it's their choice that doomed the project. They were, seriously, saying that it was a lack of requirement, or that the "users changed their mind", while it was not true at all (I was there, and I was not in either side, I just observed), the situation was well known from the start. The problem was they insisted to apply YAGNI as if they understood better than the other collaborators what as needed.
> We think you're playing slots and remembering only the wins, believing that you're just naturally talented at predicting the future.
You literally just said "ive always noticed that abstractions which are front loaded are nearly ALWAYS worse than abstractions built with hindsight".
This is literally you remembering the amount of "win" and the amount of "loose".
> Ive seen this attitude in hundreds of devs. They all think theyre uniquely able to anticipate the code base's future needs.
That's exactly my point (and I'm not a dev).
When you are saying "abstraction is better built in hindsight", you are just thinking you are smarter than other people.
When the situation is that it is difficult to understand what we will need, the solution is to discuss together to understand what we will need. We may get it wrong sometimes, but we will get it right sometimes. If someone just decides to ignore other collaborators opinion and decides "we will need this abstraction", this person has way more chance to be wrong. If someone just decides to ignore other collaborators opinion and decides "we will not need this abstraction", this person has way more chance to be wrong too.
YAGNI is just someone noticing that building a big house without following the plan led to extra work because they have to demolish the bits they've built on next door property, so they decide to build a small house without following the plan.
My judgement is based upon my experience trying it both ways many times over the course of decades.
>To avoid over-building, the solution is not to invent a rule that says "just don't build".
It isnt a rule that says dont build what you need now. It is a rule that says dont try to anticipate what architectures or abstractions might be needed in the future.
>Again, you cannot know if it is worse or not.
I used to think like you when I was more junior (most do), so it's not like I dont have a lot of practice thinking that YAGNI applied only sometimes.
It was hard experience that taught me that it was pretty universal.
You miss my point: if you are the person who develop the code, your judgement is biased, because you are not the user. You will judge the success without knowing if you delivered what the user needed or not. I saw it again and again, especially with devs who have a lot of experience, because they don't realise that the blind spot is independent to experience and get a false sense of confidence.
> It isnt a rule that says dont build what you need now. It is a rule that says dont try to anticipate what architectures or abstractions might be needed in the future.
And what mine and the comment I answered are saying is that unfortunately YAGNI is badly designed in a way that leads devs to think there is only two options: 1. anticipate what architectures or abstractions might be needed in the future, 2. not anticipate anything. The correct solution is not to anticipate what __might__ be needed, it is to listen to people who have a better idea of what __is__ needed.
Again (but are you even reading what I said, you totally ignored some of the points in my previous comment), we all agree here that over-building or jumping to architecture or abstraction that will not be needed is a bad thing. But YAGNI as a solution to this problem is stupid. The solution is to be careful with the assumption and cross-check with the team (which include non-dev). YAGNI recommends to treat one ASSUMPTION ("it will not be needed") as default, which is as stupid as assuming the opposite. And the reason devs think it works is that over-development has externalities that affect devs (a bloated software is harder to manage) while under-development has externalities that affect non-devs (users have to live with the absence of features, delivering something that does half the job is accepted by the users because it is better than nothing and because they don't know if the missing features is just "irreducible complexity" that devs cannot fix).
> I used to think like you when I was more junior (most do), so it's not like I dont have a lot of practice thinking that YAGNI applied only sometimes.
100% of the devs who created bad software applying YAGNI stupidly said exactly that. These bad software were created because these devs thought they had plenty of experience and that they knew better.
(and by the way, I'm not junior, and I have delivered a lot of code that ended up in production, mainly when I had to step up when devs were not able to do so, sometimes because they were saying "YAGNI")
> It was hard experience that taught me that it was pretty universal.
Exactly what the devs who messed up the projects I have as examples have said.
It's not an objective answer that "you really not gonna need that". It's more "No clear explanation about that abstraction? You ain't gonna need it".
> Chet said, “You don’t understand. We’re definitely going to need it. See, here’s an example…”
> Me (interrupting), “You aren’t going to need it.”
> Chet, get frustrated, “But we really are…”
> Me, “You aren’t going to need it.”
This is a clear example of YAGNI being used when the dev, actively, does not care if the other person has any argument to defend it will be needed.
YAGNI itself is badly designed, it gives the wrong answer. It should be "Build Thing Carefully": no abstraction if no argument, abstraction if no good argument beyond "YAaGnNIii".
And I know devs would just say "but devs who don't listen is super rare", but it is not true: you probably read the article and did not flinch, not noticing that it's a clear situation where the dev actively refuse to listen to the arguments. How many time did you witness or participate to such situation and still think it never happens?
At the end, I don't understand: just do "Build Thing Carefully", where what you built is well-thought, and not only you get YAGNI for free, but you also avoid the problem with refusing to build something that is needed.
The first paragraph set the context
You can solve today’s problem and do some groundwork to extend later. What you don’t do is solving today’s problem with a solution for a future problem.Whatever complicated thing that may be wanted, meaning you don’t have the full specification, as it’s not a current problem for a stakeholder.
In systems design, you’re solving problems belonging to the stakeholder, the project resources, and engineering needs and constraints. Going outside the union of those sets is overengineer, building things no one needs, costing resources that should be allocated to other things, and complicating the design because other things need to react to that new feature.
> YAGNI itself is badly designed, it gives the wrong answer. It should be "Build Thing Carefully": no abstraction if no argument, abstraction if no good argument beyond "YAaGnNIii".
YAGNI is not a case again against abstraction. It’s a case against features. You can always design code to modularize and decouple an implementation from where it’s used. What you don’t do is creating extra code for things that are not needed yet.
Why? Because anything that is going to be needed between now and that X moment in the future will have to take your design into account. The cost may be negligible, but often it’s not.
IMO, there’s no argument that can stand against “This is not part of the current requirements”. Solving future requirements ahead of time is a fool’s errand. But you can always make the current design flexible enough for future changes.
The first paragraph is exactly what I've observed that make me think YAGNI is a bad practice.
3 weeks is very short, it's basically next Sprint. This stupid developer is, without flinching, saying, "we may (or may not) already know that what we are building during this sprint will not be suitable to next sprint, but let's build it anyway because YAGNI".
How is that not stupid? Just clarify. Just say "oh? ok, maybe it is a good idea, let's have a look". Don't interrupt with "YAGNI" like it is done in the article. And don't pretend that this is smarter than doing exactly the equivalent stupid thing of jumping into over-engineering without checking.
It is really crazy to me that people don't read the beginning of this article and don't scream "WTF, why is this dev so stupid".
Don't get me wrong, maybe Chet is an idiot and came up with a over-designed solution. The problem is that YAGNI does not care: YAGNI applies both if Chet is an idiot or if Chet is a stakeholder that know better than the dev what the direction should be.
You are saying "you don’t have the full specification", but you have no idea if you have the full specification or not. The whole text is totally compatible with a situation where you exactly have the full specification, where the devs are being explained what is coming soon, and that one dev is just plugging his ears: "nanana, YAGNI, I don't want to hear what comes next".
That's exactly my problem with YAGNI: when you read this article, you should hear alarm bells. The fact that the author just chooses to not even try to check if Chet is correct or not should be a red flag. But because you have drunk the cool-aid of YAGNI, you don't even notice that the correct solution for the dev was not to flatly block the discussion with "you ain't gonna need it", but "yeah, let's discuss this, are you really really sure we will need it, are you sure it's not over-engineered. If not, great, let's do like that."
> In systems design, you’re solving problems belonging to the stakeholder, the project resources, and engineering needs and constraints. Going outside the union of those sets is overengineer, building things no one needs, costing resources that should be allocated to other things, and complicating the design because other things need to react to that new feature.
Again, I have been in these situations, and I have seen, with my own eyes, that what you say is incorrect.
I have acted as a developer, as a architect, as a stakeholder, and as an observer seeing devs and stakeholders trying to work together.
What I've observe is more nuanced than that:
- if a dev comes up with some abstraction, there is indeed some chance this is a waste of time and this abstraction is not needed
- if a non-dev pushes for some abstraction or structure, there is some chance that it is a waste of time, but also a lot of chance that it is not, and this is not negligible at all and in fact crucial for doing a good work.
- if a dev says YAGNI, there is close to 90-100% chance that they have no understanding of what is the big picture, which is a problem anyway. If they had some understanding of what is the big picture, they will not say YAGNI, they will say "oh? are you sure? it is not compatible with my understanding, but maybe I'm wrong, let's clarify".
- these devs are very very unaware of how inefficient they are. They deliver things that does not correspond to what the stakeholders wanted, but then don't have a relationship close enough with the users for them to notice that it's suboptimal, or blame it on the stakeholders or on the timeframe or on other things.
> Why? Because anything that is going to be needed between now and that X moment in the future will have to take your design into account.
But isn't that exactly the point? In this article, you and the author have no idea if the design you propose to do right now is compatible with what is needed. In this article, the author shut down the question of "let's think about what is needed", they just said "someone decomposed this piece of work into few steps, so I will do each piece blindly without looking at the big picture, because otherwise it is not YAGNI".
> IMO, there’s no argument that can stand against “This is not part of the current requirements”
You should always assume that requirements are wrong. If someone is coming to you saying "hey, I think I've understood that what is needed is ...", you should never answer then "shut up, we do the requirements blindly". If there are doubt, just clarify instead of putting your head in the sand with YAGNI.
The reason the requirements should be assumed as wrong is not because the person who came up with the requirements is incompetent, but it is because requirements are impossible to come up with correctly. Because they require the person who come up with the requirements to already know exactly all the subtleties in all areas of expertise. Imagine that person is a non-dev. They have a good understanding of what they want. But how can they know that within ThingyDB, what people call an integer is in fact what normal people will call a fraction. So they say "we want an integer", and the devs deliver something that return a fraction. And if the non-dev says "it's not what I had in mind", then the devs will say "well your requirements were bad". Both it cuts both way: it is also not the devs fault if in their context, "integer" means that specific object. Both interlocutors don't know what they don't know. They cannot write requirements where every single word is over-defined just in case.
(And if you have the opportunity, ask a dev team to come up with requirement outside of their subject of expertise, it is usually hilarious. But also a really good eye-opening exercise for these devs who were condescending towards the non-devs)
This is an obvious case to illustrate, but this is very close to what happen in practice. An example I have in mind is between the Project team, where they collaborated with "organisation", which are just other partner companies, and the Dev team, where they had "organisation_id" used for authentication. And of course, no one noticed that the same company would have several organisation_id because they had different project and different contact person. The devs were convinced that several entities that were in fact the same organisation (according to the common sense definition) were, according to them, several different organisations.
The complicated solution is trying to solve two problems at once, and one of them does not exist yet. It’s speculative.
> The fact that the author just chooses to not even try to check if Chet is correct or not should be a red flag.
Chet himself says that the thing will be necessary 3 weeks from now, implying that it’s not necessary today.
You can anticipate changes and plan for it. You can brainstorm it. You can even question the current requirements. What you don’t do is solving something that does not exist.
When we say YAGNI, that means the problem you’re stating, even when reasonable by itself, does not apply to the current context. It’s easier to revise a simple design later when needed, than refactoring a complex one that have a flawed assumption.
Very little, or possible nothing at all, is going to change in 3 weeks. If you are that myopic - as the XP people were - then constant failure is not going to be surprising. It will be expected.