Rendered at 03:50:33 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
phamilton 9 hours ago [-]
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.
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 9 hours ago [-]
> 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.
mohamedkoubaa 7 hours ago [-]
Ironically, AI assisted/generated code is not trending in the direction of the ability to safely and quickly change. Especially when piloted poorly
cassianoleal 6 hours ago [-]
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 4 hours ago [-]
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 3 hours ago [-]
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 30 minutes ago [-]
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 42 minutes ago [-]
>> 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.
phamilton 9 hours ago [-]
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.
cassianoleal 8 hours ago [-]
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.
sublinear 8 hours ago [-]
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 8 hours ago [-]
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.
sublinear 8 hours ago [-]
[dead]
majormajor 3 hours ago [-]
> 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.
rednb 7 hours ago [-]
> 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 4 hours ago [-]
Over the last couple months I've seen the debt multiplication in some OSS projects. It's like premature aging of a codebase.
lmm 3 hours ago [-]
> 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 1 hours ago [-]
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.
samrus 7 hours ago [-]
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
skybrian 9 hours ago [-]
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 4 hours ago [-]
> 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 4 hours ago [-]
What corresponds to owning an option?
skydhash 3 hours ago [-]
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 2 hours ago [-]
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.
marifjeren 9 hours ago [-]
> 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 8 hours ago [-]
> 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 8 hours ago [-]
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 6 hours ago [-]
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 4 hours ago [-]
The article does not say this.
croemer 3 hours ago [-]
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
SV_BubbleTime 3 hours ago [-]
AI 2026 still uses em dash. Next year, no such luck.
sebastianconcpt 9 hours ago [-]
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.
passive 8 hours ago [-]
(In general, I think we don't do enough to emphasize best practices in the era of AI, but...)
What Kent completely ignores here, as far a I can tell, is that there is significant value in finding out sooner what the needed features are. Building speculative structure can be a forcing function to establish requirements, because at least you start exposing failure modes. It might be more expensive than waiting, so hopefully you don't do it for most of your requirements, but sometimes it's your best option.
Building the wrong thing is now a much less expensive option, and that means the calculation around YAGNI is different. But it's still a calculation, and for now, each team needs to figure out how it has changed for them.
skydhash 3 hours ago [-]
> What Kent completely ignores here, as far a I can tell, is that there is significant value in finding out sooner what the needed features are.
But you're already know them, they come from your requirements and the design of the system that will fulfill those requirements. YAGNI is about creating something that is not part of the current requirements because you expect those requirements to change later. It's not about fleshing your current requirements and constraints (which mostly come with conversations with your stakeholders users/customer, your resources, and the engineering constraints and talents).
Creating prototypes only have value if you use them in your conversation with your stakeholders, building a project management model, or doing research for engineering purposes. Anything else is putting the cart before the horse.
MoreQARespect 8 hours ago [-]
>Building speculative structure can be a forcing function to establish requirements
Sure, if you're doing it as a spike but if you're not throwing the code away then it functions as a forcing function for creating slop.
mrkeen 6 hours ago [-]
At some point for me something flipped.
I YAGNI the concretion and write the abstract-as-possible version.
Do I write a UserStore? That would be the simplest, right? Well no, I might not need that particular formulation of a User. So I just make a Store of anything-which-is-storable.
If you're not used to it, it looks like you've over-engineered and ended up with Generics soup, but paradoxically, you're committing yourself the least to any concrete implementation.
2 hours ago [-]
AyanamiKaine 8 hours ago [-]
I personally think it all comes to exploring and implementing solutions for problems. There is always a cost associated with solving the wrong problem. Or implementing a bad solution for something that was not even necessary.
Sometimes software developement can devolve to, just becoming a trial-error approach instead of thinking about a set of strategies/problems to explore.
There is a good case that exploring problems further in specific direction than needed can help long term. But implementing solutions aimlessly is never a good idea.
I think this is what Kent Beck really means, critizing implementing something just in case because you might need it in the future.
antonvs 49 minutes ago [-]
> Chet, eyes going up to the ceiling, pausing, “Oh.” Walks away.
That's the first step in routing around damage. In this case, Kent Beck is the damage, not being willing to listen to what a teammate has to say about the design of a system.
My general principal is the cost of deleting code should be as low as possible and that includes the entire application as long as the data is around and easy to repurpose then the program itself should be as deletable as possible
gste 8 hours ago [-]
"When you build structure before the feature arrives, you’re committing on a guess."
I would argue that you are guessing either way. It could be probable that your feature will arrive, but not certain. It's a probability. If you don't build structure now, there's a cost for refactoring. If you build prematurely and the feature never arrives, you wasted effort.
What's the cost, probability and trade off between those possibilities? Obviously it depends. The whole YAGNI idea is a massive generalisation by design. Ultimately it depends on the circumstance.
Either way, it's often full of guessing and hand waving. It's the same problem as giving reliable work estimates. Certain software developers don't cope well with an uncertain world and look for black-and-white rules for everything.
geetee 9 hours ago [-]
[flagged]
svat 8 hours ago [-]
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 8 hours ago [-]
This sounded like generated text to me. "The gap" etc
gste 7 hours ago [-]
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.
rkachowski 6 hours ago [-]
I don't know what happened to Kent Beck, a few of his recent articles seem to be devoid of substance.
simoncion 3 hours ago [-]
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.
mh2266 9 hours ago [-]
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.
antonvs 7 hours ago [-]
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.
temp_praneshp 8 hours ago [-]
[flagged]
dang 5 hours ago [-]
You can't post like this here, and we ban accounts that do, so please don't.
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.
fmbb 8 hours ago [-]
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 8 hours ago [-]
> 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.
toast0 8 hours ago [-]
> 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 7 hours ago [-]
> 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.
marifjeren 9 hours ago [-]
Interesting. How do chip companies plan such projects? Do they use agile, waterfall, or some other non-software-industry frameworks?
ajb 8 hours ago [-]
They (or at least some of them) use waterfall - the real waterfall, not the bogeyman invented by agile consultants.
andrekandre 4 hours ago [-]
[dead]
zephen 8 hours ago [-]
(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 6 hours ago [-]
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 6 hours ago [-]
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."
Scubabear68 9 hours ago [-]
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”.
cauch 8 hours ago [-]
I agree.
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 8 hours ago [-]
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 7 hours ago [-]
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 7 hours ago [-]
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 5 hours ago [-]
> 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 4 hours ago [-]
>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 3 hours ago [-]
> 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 3 hours ago [-]
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".
fmbb 8 hours ago [-]
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.
ajb 8 hours ago [-]
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.
zeroonetwothree 8 hours ago [-]
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 3 hours ago [-]
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.
cauch 8 hours ago [-]
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.
gofreddygo 8 hours ago [-]
> 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 8 hours ago [-]
I still prefer the upsides of a shared vocabulary for talking about programming.
dang 8 hours ago [-]
"Please don't post shallow dismissals, especially of other people's work. A good critical comment teaches us something."
YAGNI is not about things you know you need, because then you wouldn’t write any code ever.
Scubabear68 6 hours ago [-]
This was the issue with the early agile-developed systems.
Not that they didn’t write no code, obviously, but they didn’t understand the domain and so YAGNI’d everyone to death. As a result there wasn’t enough code for the system would do what it needed to do.
The code was simple and highly testable, but didn’t actually do the job.
esafak 7 hours ago [-]
This is terrible advice. You absolutely should structure your code with a view to the future. Easily refactorable code is synonymous with good code. And using the right abstractions makes this happen. Consult a domain expert to find out what you will need. This is what experience is for.
chuckadams 6 hours ago [-]
Yes, but you shouldn't structure for a future that isn't likely to actually happen. And if you keep things reasonably modular in general, it shouldn't be a major lift to refactor if that future does arrive. Still, Beck didn't do a very good job convincing me. And if you have to always explain what "Real" Blub is and how almost no one practices Real Blub, then maybe Blub was just never a good maxim to begin with.
mrkeen 6 hours ago [-]
> And if you have to always explain what "Real" Blub is and how almost no one practices Real Blub, then maybe Blub was just never a good maxim to begin with.
I'll push back.
No-one I work with seems to practice "real DI", "real encapsulation", or "real agile", and the software is the worse for it.
chuckadams 3 hours ago [-]
Good point, though I'll try to draw a distinction between those and subjective-opinion-based slogans like "YAGNI". Maybe I should just limit it to that one: YAGNYAGNI?
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.
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.
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.
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.
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.
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.
> 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.
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
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.
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
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.
What Kent completely ignores here, as far a I can tell, is that there is significant value in finding out sooner what the needed features are. Building speculative structure can be a forcing function to establish requirements, because at least you start exposing failure modes. It might be more expensive than waiting, so hopefully you don't do it for most of your requirements, but sometimes it's your best option.
Building the wrong thing is now a much less expensive option, and that means the calculation around YAGNI is different. But it's still a calculation, and for now, each team needs to figure out how it has changed for them.
But you're already know them, they come from your requirements and the design of the system that will fulfill those requirements. YAGNI is about creating something that is not part of the current requirements because you expect those requirements to change later. It's not about fleshing your current requirements and constraints (which mostly come with conversations with your stakeholders users/customer, your resources, and the engineering constraints and talents).
Creating prototypes only have value if you use them in your conversation with your stakeholders, building a project management model, or doing research for engineering purposes. Anything else is putting the cart before the horse.
Sure, if you're doing it as a spike but if you're not throwing the code away then it functions as a forcing function for creating slop.
I YAGNI the concretion and write the abstract-as-possible version.
Do I write a UserStore? That would be the simplest, right? Well no, I might not need that particular formulation of a User. So I just make a Store of anything-which-is-storable.
If you're not used to it, it looks like you've over-engineered and ended up with Generics soup, but paradoxically, you're committing yourself the least to any concrete implementation.
Sometimes software developement can devolve to, just becoming a trial-error approach instead of thinking about a set of strategies/problems to explore.
There is a good case that exploring problems further in specific direction than needed can help long term. But implementing solutions aimlessly is never a good idea.
I think this is what Kent Beck really means, critizing implementing something just in case because you might need it in the future.
That's the first step in routing around damage. In this case, Kent Beck is the damage, not being willing to listen to what a teammate has to say about the design of a system.
I would argue that you are guessing either way. It could be probable that your feature will arrive, but not certain. It's a probability. If you don't build structure now, there's a cost for refactoring. If you build prematurely and the feature never arrives, you wasted effort.
What's the cost, probability and trade off between those possibilities? Obviously it depends. The whole YAGNI idea is a massive generalisation by design. Ultimately it depends on the circumstance.
Either way, it's often full of guessing and hand waving. It's the same problem as giving reliable work estimates. Certain software developers don't cope well with an uncertain world and look for black-and-white rules for everything.
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.
> 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 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.
https://news.ycombinator.com/newsguidelines.html
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.
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.
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."
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”.
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".
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:
https://news.ycombinator.com/newsguidelines.html
Not that they didn’t write no code, obviously, but they didn’t understand the domain and so YAGNI’d everyone to death. As a result there wasn’t enough code for the system would do what it needed to do.
The code was simple and highly testable, but didn’t actually do the job.
I'll push back.
No-one I work with seems to practice "real DI", "real encapsulation", or "real agile", and the software is the worse for it.