More DRY Talk: Responding to 450 HackerNews comments
Well, that was unexpected. My last post (which was also my first post - ignoring an article from last year I put on here to make it look like I hadn't only written one post), blew up on HackerNews and got over 450 comments. One week later, I've had over 40,000 unique reads on it. Absolutely mind blowing stuff.
The discussion was really great actually. Even the haters were pretty reasonable and made some good points. Only a few people were overtly toxic and it was mainly funny.
I replied in a few places but it was ultimately just too difficult to keep track of it all. Reading through the comments in their entirety now, they tend to fall under a few key themes. So, I thought I'd step through each of these and add my thoughts.
DRY's not overrated, it's misunderstood / overused / misapplied / etc.
This was probably the most frequent comment that came up and it's hard to really disagree with. If you wrote this, I'm pretty sure we see eye to eye on something.
I like the word overrated because it has two variables to play with, how high it should be rated and how high it actually is rated. I think some people think that overrated means it's rated a 7/10 and should be a 3/10. In the case of DRY, I think it's more of a 9/10 but should be 7/10 situation.
I suspect some commenters would then say "why write an article about a mere 2 points of overratedness". Well, I just don't think there are really any other principles that are rated a 9/10. I don't think there are actually many other principles that are rated at all by most developers. So if potentially the only principle that is widely used by developers of all levels has some shortcomings, that's a big deal. John Aslanides sent me this tweet of his from last year which articulates this point really well.
All software idioms are bad when taken to extremes, but DRY is especially pernicious because of how deeply ingrained and unassailable it is in the collective dev psyche. It is very tempting to do it on the margin, but reliably entrenches existing tech debt when done prematurely. https://t.co/T99y0HVGCs— John Aslanides (@john_aslanides) September 21, 2021
DRY's not overrated...
...it just should be used carefully with consideration to its tradeoffs.
That sounds pretty reasonable. Maybe DRY is not overrated by you - but that does not mean it is not overrated by the general programming population.
DRY doesn't mean what you think it means
It seems to be consensus that the official definition of DRY is in the book The Pragmatic Programmer:
EVERY PIECE OF KNOWLEDGE MUST HAVE A SINGLE, UNAMBIGUOUS, AUTHORITATIVE REPRESENTATION WITHIN A SYSTEM.
It is true that this definition has a lot more nuance to it. Notwithstanding that, I really don't think most programmers are thinking about DRY in this way. And I can't blame them. The name of the principle contains all the information you need to take advice away from it. If you tell me "there's a great principle called DRY, it stands for Don't Repeat Yourself" what are the chances I'm going to investigate further to see what it really means.
This begs an interesting philosophical question - what is the principle of DRY? Is it the words written in The Pragmatic Programmer or is it the aggregate of the conceptual model that most developers have in their head about what DRY means? What if The Pragmatic Programmer was just writing down a concept that was already floating around in the heads of developers? What if instead of writing what was widely agreed to be the principle they put their own spin on it?
Anyways, at least some people on the internet seem to agree that devs are doing all kinds of crazy stuff in the name of DRY regardless of how it's technically defined.
Single Point of Truth (SPOT)
A lot of comments said we should think of DRY more like single point of truth. I think this is basically what the The Pragmatic Programmer definition above is saying as well.
If we did this, it would ease a few of my grievances with DRY. But I'd still have beef.
I kind of wish I'd made more of a point in my article about the costs of coupling - I probably would have ended up writing an entire second article though. Anyways, here's my lightning round on coupling.
If you have five separate parts of your codebase that do completely unrelated things, it is a really good idea to keep them separate. Like a really, really, really good idea. If you don't do this, and you start trying to change area 1, and you find that you need to go make knock-on changes in areas 2 through 4, you will be very frustrated. Like very, very, very frustrated.
When you couple pieces of code together that don't otherwise have anything to do with one another, you pay a big cost. This cost grows with the size of your codebase. Any time you incur this cost, you need to make sure that the cost is worth it. Putting trivially simple pieces of knowledge into common modules shared between disparate parts of your codebase in the name of SPOT is just as foolish as overusing DRY.
One commenter positioned DRY as a trade off between complexity and maintainability. Other commenters suggested similar notions that DRY helps with maintainability.
It certainly can. But it doesn't always. The less a change impacts the entire codebase, the safer it is to make. It’s definitely much easier to delete code that only has one consumer.
DRY after 3
A few people suggested a good rule of thumb is to DRY when you hit the third occurrence of something. This would probably reduce problems from DRY but it would be just be a coincidence. There's no intrinsic relationship between the number of repetitions and any of the problems I articulated. It's entirely possible it might make sense to repeat things tens of times.
"This never happens" / [this literally happening]
It was quite funny to get comments saying that no one actually writes complex code in the name of DRY immediately next to comments proposing complex solutions that purportedly solve all my issues with DRY. A couple people took to the time write out entire solutions to the order pizza function that are >2x more LOC than my examples and failed to see the irony. One person told me to write a YAML file. Another person recommended I learn about the builder pattern. Also I don't know SOLID and am a junior "YOLO developer". That last one actually sounds pretty sweet.
I thought I knew what a strawman argument was but after reading a lot of comments I'm not clear I do. I guess the claim is that I wrote a bunch of deliberately bad examples to make a point about how they are bad. Yes, the examples are totally absurd and have many problems other than those I point out. Notwithstanding that, I think they concisely illustrate some concerns with DRY that come up fairly often in real world projects.
This is full of typos.
Yes - I should have done better on this. I was reaching a point where I thought if I didn't submit the post I'd spiral into a circle of self-doubt and never do anything with it. I didn't review the final piece closely enough. Thanks to everyone who pointed me to specific typos - I appreciate that.
There were a couple pieces linked that were pretty interesting.
So anyways, thanks to everyone who read and commented. It was a very cool experience. The only bad part is I have nowhere to go but down with this blog now - hopefully some folks will continue along for the ride!
Discuss on Twitter
Subscribe to my blog via email or RSS feed.