First of all, let me apologize for the clickbait-y title, but we need to talk about Don’t Repeat Yourself (DRY) principle.
Story 1
Few ...
For further actions, you may consider blocking this person and/or reporting abuse
Of course you are entitled to your opinion. In my opinion and experience, this line of thinking, practical as it may sound, will lead you to mediocrity. I stand in the other side. I studied Chemical Engineering, but I am a senior software developer who has been nominted twice to Microsoft MVP in C#. Why? Because I do not stand mediocrity. I am the developer I am because I forbid myself from copying/pasting.
Your kind of talk leads to developers I have personally recommended to be fired. No hate, just the harsh truth.
Well, if throwing titles around and fallacy of authority is your argument then there isn't anything left to discuss I guess.
It is not a fallacy. It is a story of success. Bring me a copy/paster that has been nominated. Please. I'll wait.
Just because you were nominated to something doesn't mean you are always right or even right in this discussion. Also I don't understand how would I know other nominated people and what their coding style is. The point is - it's not an argument.
I am sure that you are a good engineer but at the same time I can see that you are set in your ways. It's not my place to change your mind I guess, it's up to you if you read it and try to see the world from different perspective or not. Nonetheless I wish you good luck :)
I do not intend to "pull rank" in order to be right. I merely explain with an example the potential great benefits of renouncing to the terrible, terrible practice of copying/pasting.
My point here is that no copy/paster will ever stand out? Why? Because it is not their code. That simple. If you want to cruise through your career being barely average, by all means, copy and paste. That's what I'm saying. I'm not pulling ranks.
Please you need to update your understanding of a developer 'standing-out'.
If you think the only way a developer can 'stand-out' is by being nominated as a Microsoft MVP n-number of times, then you need to take a sabbatical.
By no means did I ever try to imply such a thing. Your conclusion cannot possibly be following a logical path. As stated, it is an example of what you can achieve if you set yourself into a disciplined path.
Hard to be believe that that alone is what makes you a great developer.
It does. Debug the statement. If you cannot copy and paste, you must do it some other way. This invariably takes you done the path of simple things like inheritance and virtual methods to complex design patterns. While you learn all this you learn all sorts of "peripheral" knowledge. Yes, you must be knowledge-thirsty.
I think we are referring to different things when we say "copy/paste", I don't mean blindly copying stuff from StackOverflow. I mean copy/pasting code you wrote yourself, and I think that's what the article also refers to.
Exactly. I am talking about the bad practice of copying and pasting pieces of code to create repetitions as opposed to applying a better coding practice.
I mean… Donald Trump was nominated (and won, once) for President of the US. I think we can agree that a mere nomination, or even a win, doesn’t automatically imply qualification.
Your need to state and inflate your own ‘achievements’ detracts from your argument at best; at worst, it reveals your own mediocrity and insecurities.
The author makes very good points and backs them up with actual appeals authority. He uses actual logic and gives good examples.
Take yourself down a peg, bro.
Since you are so fond of logic, you should apply it while you read. I am not trying to gain traction with my nomination. It is an example of how much you can advance yourself when you forbid yourself from copying and pasting.
Try reading things correctly next time. You'll find yourself in a much better position.
Get bent with your fancy nominations. Your argument is INVALID.
Loving all the hate. LOL. It just tells me how much I have surpassed the crowd.
lol
I was one of those Devs that wrote code that was ALWAYS DRY.
I'll be honest it's so hard for me to write WET code because it's been indoctrinated into my mind all throughout college.
Most of the codebases I've worked in don't keep things DRY, I've always found myself saying "oh man, you could encapsulate this into a function and then clean this up quite a bit, why didn't they keep things dry?"
Up until recently, my new boss started to tell me, "You know those devs that are DRY devs, they need to let the application cook"
"Once you have an application working really well, you then can clean it up , but it needs to cook!"
Just this year I've realized this is true and I'm starting to like it.
You build an application with well-written code and let it cook/bake and once you have a good working product, you can identify where you can keep things DRY and clean things up a bit.
Definitely an interesting subject.
Love this,
"Once you have an application working really well, you then can clean it up , but it needs to cook!".
As a new Dev I'm finding it hard to just make stuff cook right now. I wrote a couple of apps for my job. First one is a mess of code that works, but is such a mix of different techniques I was learning as I did it. Looking at that code is both scary and exciting.
The second app is as DRY as I could make it and it certainly took me longer to get it cooking. But at the same time, I don't feel like I have to clean it up as much. I can probably find a bug in it much faster than I can in the first one. I did my best to abstract and not repeat code but sometimes you realise that maybe... just maybe... you're complicating something simple.
I had so many arguments with colleagues about copy/pasting ! Even wrote an article about it:
kissyagni.com/2022/02/17/to-dry-or...
I would add:
Why do we need to factorize code ? Because we don't want that 2 part of code having the same goal diverge. But what about 2 part of code having different goal but implemented with the same code ? Should we factorize those 2 identical code ?
Hell, no ! If you do this, you will end up one day or another with a single function (a module, an entry point, whatever) that will implement 2 different behavior with a big
if
statement. And not a singleif
, but a lot of smallif
interleaved with common behavior.Factorizing code is a good practice, but it is not a dogma.
A false abstraction is a great example of that!
Sadly dogma in software development often kills rational discussion and pragmatism. People are way too emotionally attached to some things.
More than all those rules and acronyms, it's better to follow the kaizen methodology of continuous improvement, or what some people like Uncle Bob say as "boy's scout rule" of "leaving the code better than how you found it".
I do however like to point: just because it works, doesn't mean it's done. Some people see it working and commit without even giving it a little refactoring.
Overabstraction is the root of all evil. I never say never, and absolutely don't believe in absolutes, but that's always true, 100% of the time. :)
Seriously, bad abstractions are 90% of the problems in our industry. When someone asks you how to make a ham sandwich, you don't say:
AbstractLocomotionService
to locomote theAbstractYouRepresentation
to theAbstractPantryLikeFoodItemContainer
AbstractFoodItemContainerRetriever
to retrieve theAbstractBreadItem<WhiteBreadIdentifier, StandardLoafType, [SlicedIdentifier]>
whereslices.length > 2
(the crust pieces no one wants)You get the idea.
Get the bread. Get the mayo. Get the ham. Stack in sandwich form. Eat.
I think sometimes dev spend way more time abstracting then just coding the solution and come back to refactor if it needs abstraction
It's funny, I was having a conversation similar to this just recently that lead me to talking about shipping code rather than over working it.
I think that where possible repeating is not great, but it's not deadly either.
Indeed, I often repeat myself whilst working on a solution until I know that I'm either close or have what I need and then consider if it makes sense to abstract and use many, or just leave in place and repeat somewhere else.
I think it is all too easy and often to peer pressured to make code the absolute best it can be with so many best practices that it ends up being unreadable or unmaintainable further down the road when it has not been looked at for months and now needs changing.
So I say, go with what works and ship. There will always be another revision where the question of DRY can be asked again to see if the answer needs changing.
Another reason you may want to duplicate the code is that they have to different consumers, which can independently. The effects of this are twofold:
Of course you can refactor code into reusable code units, but it ultimately comes down to balancing the qualities of the software system like maintainability and stability, which we get to do by writing and refactoring the code.
I kind of informerly follow this pattern - you can't really create the right abstraction until you understand at least 2 different use cases - but you are essentially moving towards DRY code, which is not what this article suggests.
The problem with taglines like "please repeat yourself" is that developers will read that and take it to heart. Our industry doubles in numbers every 3-4 years, meaning most developers are still pretty young, and they should not be armed with this type of mentality.
Furthermore, every line of code is maintenance, and maintenance is 70% of our lives in software. Every time you delete a line of code, that's one less thing to maintain. Lets say someone finds a bug and fixes it, but they didn't go searching around the entire codebase to see if the bug existed somewhere else? Now you're just deploying software with the same bug... fixed in one place but not others. It's a false sense of "it's fixed".
Maybe this product mentiioned in the article could make many more millions if the developers weren't makeing the same feature enhancements 20 times across 20 nearly identical files.
Maybe that first abstraction took 2 days to implement, but now the shared library is in place and all shared code can now be put there with even less effort that copy/paste. Those 2 days ended up saving them weeks in the long run.
I'm not advocating in any way that what was done in that case was a good idea, just that you can still succeed even without perfect code. I'll add a sentence there to explain that. It's fair point that this could be misunderstood.
I've just spent a few months writing an abstraction framework for interacting with our simulation hardware - we have hardware simulating fluidic movements for a medical testing device, and as part of our CI, we want to automatically test changes to the product without having someone hooked up to an eternal drip feed...
In constructing this framework, I had a few considerations, not least the assurance of maintainability, and certainly including concerns of maintainability.
One of the things is that there are several channels into the device, in the form of binary or text streams, operating in the background so we didn't lose any outputs. For those, I made sure to have abstractions in place in terms of a threaded stream reader that many other types of streams could benefit from.
On the other end, we had several types of streams that would use this same threaded stream mechanism with a couple small variations. Each
read
method was coded nearly exactly the same in about 4 lines, but with a few adjustments. I unified those adjustments into a single method (and thus, an additional abstraction).The end API functions I exposed are coded each nearly identically, except for any of their corner cases. I could actually have abstracted those further.... I did not.
At some point I decided that the abstractions and redirections were too deep and accepted a certain level of repetition at the higher levels, whilst keeping the "conceptual" (repetitious) elements genericised.
I am a fool for following a (self-coined) mantra: "Solve the general case".
Sometimes that mantra is unhelpful. There have been some projects that didn't require such zeal and precision. But I was never able to know this in advance. So I have applied those rules. Abstractions, abstractions, abstractions.
At the end of it, to figure out where something comes from, I have to delve down several layers before figuring out a single issue.
I'm not advocating anything here really.... just a personal diatribe on how it is difficult sometimes to decide when to "just do it"... and when to "think architecturally."
In my opinion, YAGNI, DRY, WET, SOLID, CUPID, GoF are all tools to be applied appropriately and I agree that vilifying it is a problem. In face to face conversations with developers of some experience, we know this to be true.
The root of that problem is clickbait titled articles. Like this one. 90% of junior devs (who we are appealing to in the articles), will read the title, share it and move on.
Your article is good. If the title wasn't so utterly terrible, I'd share it with the team. Please don't clickbait in future.
The first story explains that the code was written at the time by a novice, should we hold a novice to the same level of competence as a pro? From your quick Google search "it reduces the quality of code", if you believe in repetition you should have left their code as is.
The second story is just a developer who doesn't understand the principles of DRY. It's a function that encapsulates code, an abstraction by all ramifications, according to DRY principles you just use the function. They should have rewritten their entire language API if they feel reusing code is bad.
I agree software principles are correct 80% of the time but these principles need to be understood properly.
I think repetition is a temporary state until you figure out the right abstractions, so leaving that code as is - when it hindered further development of the codebase at this point - would be a bad choice. I don't "believe in repetition" because coding is not a religion. I think it is useful in small, healthy amounts and not something we should avoid at any cost.
I agree. But that's the point though. People treating coding principles as dogma instead of actually understanding them. I wrote this piece to convience people try to start treating it less as dogma or "good practices that you just need to apply" and start thinking more about why, how and when to apply them.
100%.
I think "please repeat yourself" fall in to:
Here is a piece of video in which Rob Pike, one of the creators of Go, explained the principle of "a little copying is better than a little dependency". He showed this with an example from the Go standard library where they made the deliberate decision to copy and paste a piece of code in order not to introduce unnecessary dependencies. (Sorry Rob, because of this you will never be nominated a MS MVP)
Great article, it has a lot of sensible ingredients in it!
The one thing that I am using instead of DRY is: "if it should behave the same, it should be the same". I think that this statement covers everything you mentioned.
I scoffed when I first read the title of this article but right now as we speak, I'm writing some production code where I'm realizing that if I go too far in DRYing up a certain pattern, it will actually make it so abstract that it will be difficult for other devs coming after me to quickly understand what's going on.
I agree that you can write WET code, let it cook for a while, and then DRY up whatever needs to be optimized instead of immediately drying up everything from the start as a dogmatic practice ( which is what I tend to do ). There is some merit in this article, as infuriating as the title may be.
Over-engineering is a killer. Agreed, however if you are developing some library, some component or similar, abstraction definitely makes you think better and it results with a better output mostly. Yet, I believe first code it, make it work, use it in real life projects to understand possible use cases. Then make it better with refactoring, abstraction, etc. For my experience, it is mostly more obtainable goal.
I think the main point is what makes your code base simpler and easier to maintain. Sometimes repeating a line of code is a lot more clearer than writing an abstraction but repeating too much it will make it harder to maintain.
I tottally agree with your point.
Thanks for the piece of data. I really cannot care any less since I'm not a US citizen.
Your ego is so high, that you better watch out to not fall from it - you may hurt yourself ;]
Yeah, that only applies to things that are volatile. My "ego" as you say, is "flying high" based on rock-solid knowledge acquirement. Unless I have a stroke or something, I'll remain "high". But thanks for worrying! 😏 And welcome to my fan base. It is amazing how people try to bring you down. As I have told others, hate demonstrations just tell me how higher I am from the average crowd.
Finally, you may want to read more than one message in a thread. Cheers, fan.
So, you like to work twice and make the development process slower to avoid thinking? I know that you don't have to overthink everything, but it's a basic thing to think before coding to avoid make a bulky and heavy project.
You need to apply more than one principle if you want to be successful! Engineer
Ignoring DRY is not a solution AT ALL! One of my top principles that I use alongside DRY is YAGNI (You Ain’t Gonna Need It) which means if you don’t need to build common library to enforce DRY, then you should not do it!! That simple!
Don’t try to use these Principles in silos and try to build a practice of applying top principles alongside each other.
My best combination is (In order of priority):
I agree, in my personal case, in the past i was fall into imaginary abstractions only because i was not want to repeat some little pice of code, by a little amoung of time. This imaginary anstractions were a headache since then.
From my experience, it is quite better first code, and then, refactor that code identifying the actual abstractions
I want to add to this, although I agree that over-abstracting code can be bad. You should not think that in the coding world there is something like temp code. That becomes the practice in the company you work at. I do believe in design sessions, the example of what you use for DRY, only shows that although the developer went to route for creating a lib, that is the potential problem he didn't plan anything, he didn't go to his team with a design document, problem statement. He just jumped making a huge decision, leading to a waste of time. DRY was not the problem here, planning was, don't just jump into coding
Can't agree more. 20 years ago I worked at a company where we used a kind of template code base to develop web portals. This base code was copy pasted every time a new page with new functionality is needed and we just made the necessary modifications, and as the base was very generic, usually very little modification were needed. We just had to make the modification that was specific to that new page / functionality the rest remained basically the same damn duplicated code. And our life was nice and easy... I have never seen a more productive way of doing development ever since. Also it was very easy to understand / modify / debug the code base which was actually in 80 % percent duplicated code. But how beautiful and generic was that duplicated code, that you could see everywhere in the application. The way that it got so generic by time, is that we always improved this generic part of the code as we worked on more and more projects, so by time it just got more and more perfect.
This kind of code base full of duplicated, generic code, needless to say is very very easy to understand, follow as you basically have the same things going on everywhere with very little alteration.Also there is so many tool you can use to modify code with repeating pattern in bulk. (e.g. sed etc..) So it is not a problem at all, but the opposite. It is very very easy to do... Of course after improving these generic code base for years, it would have been also easy to refactor and remove the duplicity. But actually if you have enough experience and you can imagine how easy is to work this way, or you have even worked with generic code templates before, you can easily understand that removing the duplicity and try to reuse the code in any other way would have just made the development more problematic, more complicated and complex. So there was no point to do that.
On the other hand If I have a look to code written with frameworks like Laravel, Symphony etc. which are popular nowadays, they are much much much worse to work with in every respect.... Much harder to understand, follow, debug, modify, learn... IMHO today with all of these over-engineered over-hyped engineering patterns and principles people just make their own life basically a living hell.They do not even have an idea that coding can be done in a much simpler way. They just follow the mainstream. Nobody wants to understand that over-complicating things, targeting complexity with more complexity are not a smart thing at all, but right the opposite! It is like people just try to show how can somebody create an incredibly over-complicated obscure solution for even the simplest problem. E,g, targeting a simple problem using these framework is a huge over kill for starting. It is like they just want to make sure nobody can understand how stuff work and then they think they are smart when nobody can understand the obscurity they create. It is kind of like a stupid mind game for people who feel like they are mentally superior. They think over-complicating things will make them look smarter. Nothing can be farther from the truth. I have also seen many very successful projects generating million of dollars in revenue used by millions of people with a code base so simple contradicting every currently popular over-complicated over-hyped principles and patterns. Lacking actually all of that. To be honest all really successful applications are like that. They target complexity with simplicity and not the opposite or any other way. The real genius is when somebody solving the complex problem with simplicity. The problem that you need to solve can be complex and complicated but not your solution. The solution for a complex problem must be not more complicated and complex than it is needed as a minimum. The problem is that people mix this up and think if they can solve simple problems in a complex way then they can also do the opposite. It can be further from the truth. I also have to say that after 20+ years in development I have seen many many different code base. I have seen many duplicated code. The problem is not the duplication itself. It all depends what kind of code gets duplicated. The problem is when horrible code gets duplicated, and this is what happens most of the time and this is why code duplication has a bad reputation. But again it is not the duplication itself theproblem... When good quality code gets duplicated with a good reason, then it is actually very good thing and does not necessarily need any changing.
The stupidity is to blame the duplication itself instead of the horrible code that gets duplicated.
If you think about this is how these stupid principles get built by idiots.
Like "code duplication" is the root if the evil LOL
If you think about it, it is actually scary how many stupid "engineer" are there in this industry to make it possible to these baseless "principles" to raise to existence.
There are times that repeating yourself can be desirable or necessary, but all good software development starts with minimising duplication. That's because all code requires testing and maintenance so it's a liability. You want less if it, not more.
Unfortunately you haven't understood the meaning of DRY principle. DRY is NEVER dead!
DRY principle means "Do not repeat YOUR BUSINESS LOGICS"
Copying some/part of a package/library is ALWAYS OK (e.g. not to include a whole big package/library when you'll be using 5% of it; in this case you can copy only part of what you need, tailor it according to your business logics et voila!)
If you fail to apply the DRY principle in your business-logics (services), then the mess you'll be creating will produce technical debt, maintenance issues and much more!
[Edited]
I am a PHP developer, but do some Golang also. One of the Go proverbs is "A little copying is better than a little dependency." go-proverbs.github.io/
Now I love Tailwind CSS.
Sarcasm. The tool of the weak. No worries. I'll let you know if I'm nominated. Cheers!
Could not finish reading. This is ultimately nonsense. In no cases, regardless of your attempts to imprint some rationale to it, is a good thing to repeat code. I have personally fixed one bug 98 times.
To quote one of your so-called samples, you imply that spending 2 days for 3 lines of code is madness. When you over simplify like that, yes, it does sound like madness. But the DRY principle is not there for 3 lines of code, it is there to be a guiding beacon in your search for perfection and self advancement. Just because you find one case where it sounds bad, it doesn't mean that there will be more cases like that, or that other cases should be considered too.
I have more than once started with an abstraction or a library with a single piece only to see it grow over time while I thank myself for DRY'ing it 3 months later.
In short, nonsense. Apologies for the blunt comment, but it needs to be said.
I think that you should at least read the whole thing before labeling something as nonsense. Otherwise it's dishonest and it's clear that you are reacting emotionally, not having a rational conversation. I encourage you to read the whole thing because we may think more similar than you think - and maybe it's not all nonsense :)
I also encourage you to read content I linked as it adds a lot to the argument.
If you read the whole thing you'll see that it's not the scenario I'm advocating for. What I'm advocating for is giving yourself space to uncover abstractions instead of imaging them through iteration. That's it
Yep, it is madness. And it's there to show how DRY is often misunderstood and taken to extremes by people who ultimately do not understand it.
I don't think "search for perfection" is what a software developer should do. People who search for perfection often can risk the entire project because they can't focus on the task at hand. That said I'm not saying that's your case, just what comes to my mind when I hear these words.
Hi. I think you have a point. Maybe I should have finished reading. In all honesty, though, you get to a point where you just say "no more". I'll try.
Let me explain the faulty part in your plan: Code has the potential to have bugs in it. Any code, big or small. Code has also the potential to grow, to become more complex in order to better serve its ever-changing purpose. These two reasons alone are enough to invalidate what you state. Why? Because if I have a copy/paste party, I will have to have a copy/paste enhancement/bug fixing party. The 98 bugs I corrected? The bug was there unintentionally. The persons who copied over that many times did not notice it. It was a 7-line handler. Would you say that 7 lines are worth the trouble if we were to follow your logic? Probably not worth the trouble right? Well, 98 times the bug repeated.
So yes, I stand by my conclusion.
Depending on the situation - I would say around 3 or 5-ish time I'd repeat it I would put it into a separate function. Depends on the context though. 98 times is just careless and way too much. As I said - there is a healthy amount of repetition, 98 is not healthy. And repetition should be a temporary state until the right abstraction is uncovered. Sometimes it's before you commit, sometimes it's before you make a PR, sometimes longer. The point is - don't be afraid to copy stuff because of the dogma and stigma.
Do you think different developers in the team will be counting the number of times the code has been duplicated, in order to say "wait a minute, let's just stop for a second", and then refactor? Once a copy/paster, always a copy/paster. That's not real life Mr. Rafal. Your argument still doesn't stand.
Reflect on this:
It's all about the long run. Copy/pasters are doomed to always be copy/pasters.
DRY when you see a behavior exists over three times, or be a coder in the rest of your programing life
I fully agree. DRY is not a monster nor should it be seen as such. Knowing how to balance between the two worlds and build the expected solution.
Re-thinking the DRY pattern is aligned with the school within microservices around "share nothing".
Good read.
"Repeating yourself is basically giving yourself the time and space to come up with the right abstractions"
Well put. Good read
Worth nothing. Anyway all duplications are a technical debt. You can fix it later or sooner. Just don't collect it.
Sometimes, I modify duplicate code using find and replace all.
BTW, the AHA programming link is broken
please i need mentor on html. am a newbie in coding. i ust need someone to mentor me....