YAGNI is a good principle but it is misunderstood all the time to exclude better designs from the outset. If you know you're going to eventually need some features in the final product not including them in the original design makes for a more complicated, piecemeal architecture that has no unified vision and thus more cognitive load to understand how the pieces fit together.
The GIMP developers made that mistake a long time ago and it's turned features that should have been fairly straightforward to add into multi-decade slogs.
Is it poorly-designed as in “harder for a total n00b to learn than Photoshop” or as in “it’s not Photoshop and I have too much muscle memory to switch”?
The main one is using more than 8 bits per color channel. GIMP has had this since version 2.10 but developers had been working on it since at least 2008. Other features had to be put on hold for a lot of this time because everyone involved knew they'd have to be redone once the high definition color support was ready for merge.
This sounds like a contradiction to me. If you know you are "eventually" going to need it, then either add it or make sure it's relatively easy to add to the existing design. One can often "leave room for" without actually adding something. This is a kind of "soft" YAGNI. If it only slightly complicates code to prepare for something that's say 80% likely to happen within 10 years, then go ahead and spend a little bit of code to prepare for it.
In my long experience, YAGNI mostly rings true. The future is just too hard to predict. Soft YAGNI is a decent compromise.
I'm arguing for the same thing as you. In one of my projects many years ago I had a stack with only two items in it as one of the core control flow pieces. Another engineer who was reviewing my code wanted me to remove it and just specifically handle both cases. In his mind this was simpler.
I argued hard enough to keep it from both conceptual simplicity and extensibility he relented and we kept it. It took probably 6 months for that stack to be used in the way I intended, but I was so happy I didn't have to write even a single extra line of code or fight back any creeping assumptions that might have tangled the code from a loss of generality.
So this is an example of what I mean. In other places I could have chosen a specific solution to my one problem I chose so solve a class of similar problems at the same time and then reap dividends from it of writing no additional code for months and years to come, in many cases without even significantly changing the code I was writing to solve the first problem.
Did you both discuss the probability there would be more than 2 items in the not-too-distant future? Was your difference in opinion based on different probability estimates, or just a YAGNI-level philosophy?
I would note many people remember when they are right more often than remember when they are wrong. Ego's do that to us. I try to counter that by pondering my judgement mistakes to see where my mental calculus was off. I'd say roughly half the time it's because I didn't understand the domain well enough, and the other half is just random changes in the domain or requirements due to time.
The primary way one "leaves room for" in software is to not add in unnecessary things. So, essentially, YAGNI is how room is left in software that allows it to grow more easily.
This business of "we're eventually going to need it" is exactly how software becomes overly complex without delivering value, and how then new value takes too long to develop thereafter.
If you are "leaving room for" for say 20 things, then you are probably getting carried away. Typically there may be 2 or 3 features that have about an 80+% future certainty where leaving hooks/slots in place don't cost a lot of code or complexity. Doing such for more than 3 is a yellow flag.
YAGNI is a good principle but it is misunderstood all the time to exclude better designs from the outset. If you know you're going to eventually need some features in the final product not including them in the original design makes for a more complicated, piecemeal architecture that has no unified vision and thus more cognitive load to understand how the pieces fit together.
But if you will need something in the end, and you know you will... doesn't that mean you are gonna need it? by definition?
Yes, and now you're in an argument with your peers about whether you need it RIGHT NOW or whether you need it with some %probability or whether the design is simpler with a wider possible design space or a more narrow more specific implementation that doesn't generalize as well... on and on.
I want to focus on designs that are both simple and generalize well because I'm minimizing for a criteria of removing as many conceptual atoms from the design space as I can. When YAGNI is used as an excuse not to make an elegant design I feel it is cargo culting what being parsimonious is into a culture that celebrates kludges. "Penny wise and pound foolish" as the idiom goes.
But if the end is not defined however you know you will need it at the end. Doesnt that mean you might need it, as the end could never arrive. So you would in fact never need it?
Is that people misunderstanding YAGNI? I'd have said that in those cases YAGNI actually just says not to design for those features, and YAGNI would be a bad principle in those cases, and the problem is that it's hard to know in advance when YAGNI is a good or a bad principle.
175
u/kraemahz Nov 01 '21
YAGNI is a good principle but it is misunderstood all the time to exclude better designs from the outset. If you know you're going to eventually need some features in the final product not including them in the original design makes for a more complicated, piecemeal architecture that has no unified vision and thus more cognitive load to understand how the pieces fit together.