14 ms·
> Instead of our code being architected around the concept of how pizzas are made in the abstract, its architecture is tightly coupled to the specific needs of
by mavu 4y ago
> Instead of our code being architected around the concept of how pizzas are made in the abstract, its architecture is tightly coupled to the specific needs of these two pizzas that we happened to be dealing with. The chance that we will be putting this code back the way it was is extremely high.
Mistake 1: Switch from DRY to premature optimization.
> You might think that legit reasonable developers but would not actually do something like this and would instead go back to the existing invocations and modify them to get a nice solution, but I've seen this happen all over the place.
Mistake 2: Assumption of incompetence to support your argument.
> . As soon as we start the thought process of thinking how to avoid a copy paste and refactor instead, we are losing the complexity battle.
Mistake 3: Strawman argument. DRY does NOT lead to over-complicating things.
Overcomplicating things leads to overcomplicating things.
Now, i wasted 5 minutes, so you can waste some more to reply to this comment, instead of completely ignoring this dumb random blog post.
- fartsucker69 4y agoI don't read coding opinion articles like OP but I like to check out comments. > DRY does NOT lead to over-complicating things. That is not true. I dive around foreign code bases a lot and dry-ness is actually a significant complicating factor in understanding code, because you're jumping around a lot (as in physically to different files or just a few screens away in the same file). As in, inherently every time it's used, not just in situations where it's used in a complicated way. This sounds dumb but it just simply is much harder to keep context about what's going on around if you can't refer back to it because it's on the same screen or one short mouse scroll above or below your current screen. That obviously doesn't mean you should leave copy pasted versions of the same code over your code base. But it's important to consider that refactorization of that code into something common that gets called from multiple places as something that you don't get for free, but that is an active trade off which you usually have to apply to prevent bugs (changing one code location and not the other) or simple code bloat. In practice this is very relevant when you suspect something might be repeated in the future, but you're not sure. Imo: Just don't factor it out into anything, leave it there, in place, in the code.
- MichaelGlass 4y agoAgreed. To use the example from the article `make_pizza(["pepperoni"])` What does `make_pizza()` do? It could be a lot or it could be a little. It could have side-effects or not. Now I have to read another function to understand it, rather than easily skimming the ~four lines of code that I would have to repeat. I think the article fails to show particularly problematic examples of DRY. E.g. merging two ~similar functions and adding a conditional for the non-shared codepaths. shudders
- bjornsing 4y agoYup. But I guess that typically happens in steps. So next DRY-programmer that comes along will add a cheezeFilledCrust boolean to that make_pizza function and so on. Every time it will seem more reasonable to add another boolean, because otherwise you have to remove the make_pizza function, and there would be SO MUCH CODE DUPLICATION. I’ve seen this again and again in the field and I wholeheartedly agree with the sentiment in the OP. IMHO different code paths should only share code if there is good reason to believe that the code will be identical forever.
- 411111111111111 4y agoNow the next genius turns up and says that make pizza is at it's core always a n-step domain process. So now you've dumped it down to an interface with a default implementation which calls the create_dough, add_toppings, bake_pizza interfaces in order, each of which are either passed in callbacks or discovered through reflection. We can even sprinkle in some custom DSL to "abstract away" common step like putting the product into the oven correctly! Jr's will never understand when why and what is effectively excecuted at runtime. Honestly, at this point I enjoy working with this kind of code. It's always such a high entertainment value and I get paid by the hour, so whatever
- grog454 4y agoSome languages handle massive parameter lists better than other (ex with defaults). There are also design patterns for this type of problem (ex a PizzaBuilder).
- bjornsing 4y agoTLDR: If you do DRY in moderation it’s great (as the OP explicitly says).
- DougBTX 4y agoWhat's funny is that DRY was first popularised in the Pragmatic Programmer[0] book, and "coincidental" duplication is explicitly addressed right there on page 34, "not all code duplication is knowledge duplication... the code is the same but the knowledge is different... that's a coincidence, not a duplication." [0] https://www.amazon.co.uk/Pragmatic-Programmer-journey-mastery-Anniversary/dp/0135957052 https://www.amazon.co.uk/Pragmatic-Programmer-journey-master...
- loudgas 4y agoI believe this was added in the 20th anniversary edition to address the overuse of DRY following the original edition.
- hsn915 4y ago> Mistake 1: Switch from DRY to premature optimization. "Premature optimization" is largely a bogus concept, because the meaning of "optimization" has shifted a lot since the concept was first created. People now use optimization to mean "sensible design that does not needlessly waste resources". In this meaning of optimization, "premature optimization" is a bogus concept. You should absolutely ALWAYS write non-pessimized code by default. What the original concept referred to is what people now call "micro optimizations". Sure, premature micro optimizations is often a waste of time. But this is irrelevant to the context of this discussion.
- gopalv 4y ago> In this meaning of optimization, "premature optimization" is a bogus concept. The idea is that you can end up optimizing before you know the entire use-case, because software engineering isn't like building bridges or skyscrapers. I'm a performance geek, but I love code I can easily change rather than code that is fast until some customers have touched it. Mostly out of experience with PMs with selection bias on who they get feedback from ("faster horses" or "wires we can hook phones to"). The first thing to optimize is how fast you can solve a new problem that you didn't think about - or as my guru said "the biggest performance improvement is when code goes from not working to working properly". The other problem with highly optimized code is that it is often checked-in after all the optimizations, so the evolution of thinking is lost entirely. I'd love to see a working bit + 25 commits to optimize it rather than 1 squashed commit. Optimized code that works usually doesn't suffer from this commentary so the biggest opponents I have with this are the most skilled people who write code with barely any bugs - I don't bother fighting them much, but the "fun" people with work understand my point even if they write great code first time around. These two are mostly why I talk to people about not prematurely optimizing things, because I end up "fixing" code written by 15 or more people which has performance issues after integration (or on first contact with customer).
- hsn915 4y agoCode that is sensibly written in a non-pessimized manner is not hard to read or modify. That's the whole point of my comment. The word "optimization" as currently used confabulates two separate concepts: - Non-pessimization (new meaning of "optimization") - Micro-optimization (original meaning of "optimization") You're talking about micro optimized code, and I'm talking about simple non-pessimized code.
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- hinkley 4y ago> Assumption of incompetence to support your argument. Okay, but it kind of is about incompetence. And by “it” I mean everything. Look, we all remember that first time we all realized that adults are just winging it most of the time. Almost nobody knows what they are doing. Half the people who “know” actually know the least. > DRY does NOT lead to over-complicating things. Don’t Repeat Yourself is a terrible acronym because what it stands for is exactly the opposite of what people do. Not doing something is avoidance, opting out, like “don’t push your sister” vs “be nice to your sister”. What most people do is they realize they have already repeated themselves, or someone else, and they rip it out. They deduplicate their code. Avoidance definitely can “lead” somewhere, but deduplication is active, and that can often be headed the wrong way, either directly or obliquely. The Rule of Three is much clearer on this. You get one. There’s nothing to do when you see you’ve duplicated code - except to check if you’re the first or not.
- sebastianconcpt 4y agoI wannabe your friend hahaha No really, you're absolutely on point. The post is not worth the time, the case against DRY is too weak. Sounds like a kid complaining about pushing DRY in a direction that overcomplicated things for him because of himself and instead of improving himself he choosed to attack "an uncomfortable principle".
- dspillett 4y ago> Mistake 1: Switch from DRY to premature optimization. Though note that DRY can itself be premature optimisation of the codebase.
- lucideer 4y ago> Mistake 1: Switch from DRY to premature optimization. Mistake 1a: Conflating the term "premature optimization" - it doesn't apply here. Premature optimization is about runtime performance, DRY is about optimising maintenance overhead. Mistake 1b: (good) DRY can't be done early (it's a continuous process throughout project development). > Mistake 2: Assumption of incompetence to support your argument. Mistake 2: Assuming you're never working in teams leveraging peers' of varying experience and technical focus. The presumption of re-usability is absolutely the most common red flag I've seen with DRY: I've seen it with a lot of very senior / experienced devs. You can call them incompetent, but there's plenty of them and we have to work with them. Articles like this help. > Mistake 3: Strawman argument. DRY does NOT lead to over-complicating things. Overcomplicating things leads to overcomplicating things. This statement concerns me. DRY very obviously and demonstrably leads to over-complicating things (excessive / ballooning parametrisation is just one of many very simple examples of this). If you can't see this I would have my own concerns about competence...
- gcassie 4y agoThanks for having my back. #3 is an overwhelming real world phenomenon. In fact, I posted my article on reddit and someone wrote back a comment with a huge OOP solution that would mitigate all my problems. Not sure that reader got to point #3.
- Ensorceled 4y agoThe article is claiming that slavish devotion to DRY results in issues. You are giving names to the issues resulting and calling the article bad.
- civilized 4y ago> Mistake 1: Switch from DRY to premature optimization. Fallacy: False Dichotomy and No True Scotsman. "Things are either DRY or premature optimization and can't be both" "No TRUE application of DRY would ever be a premature optimization"
- DavidSharff 4y ago> Overcomplicating things leads to overcomplicating things. This would be the most efficient title, subtitle, and entire contents of most posts about programming principles. However, each reader has to have a similar enough perspective, background, and experience to understand and apply it. In that sense, the trend line measuring the value of commenting about comments about random blog posts indeed indicates wasted time, but hopefully it's a local minima. My pithy corollary to your helpful tautology is a quote from Tommy Angelo that's stuck with me since my poker days: "The decisions that trouble us most are the ones that matter least." Decisions are necessarily difficult to make when the expected value of either outcome are similar. We waste an awful lot of time on choices that could have been made just as well with a coin flip. So there you go world: two quotes that are generally useful about generalities that are locked, loaded, and ready to shoot you in the foot when misapplied. Edit: formatting improvement.
- ravenstine 4y ago> Mistake 3: Strawman argument. DRY does NOT lead to over-complicating things. Overcomplicating things leads to overcomplicating things. Sure, I agree, except DRY is probably the second greatest gateway drug to overcomplicating things to OOP. Actually, they really hand-in-hand since OOP features are often used to DRY things. DRY can easily go too far because fundamentally it's about centralizing ideas with the premise that different operations can and should share units, even though a "writeSomeFileToDisk" function doesn't necessarily have to do the exact same thing between different higher-level operations. Because so many engineers emphasize "elegance", if a set of functions seem similar enough, they pressure themselves to write code that is shareable, hence more abstract. Abstractions are inherently more complicated and hard to understand, not the other way around. Rather than having very simple "molecules" of code that can be understood on their own, there is instead a much larger molecule of nodes that are connected by abstract dependencies, and those nodes may only have dependencies in common. DRY should be done sensibly, but teaching DRY is a problem in our industry because we don't teach engineering discipline. We teach principles like DRY and OOP, and even YAGNI as if they are tenets of a religion.
- SomeCallMeTim 4y agoArticle tl;dr: Design is hard and can't be boiled down into applying pithy mindlessly. For what it's worth, I agree with your points and disagree with the various counterpoints that were posted; "optimization" can mean a lot of things, and I for one understand what you mean.