1. 33

  2. 10

    I wrote a similar post several years ago.

    Be warned it’s not written very well and is heavy on Mozilla lingo. But the main takeaway is the concept of IFFY (in flux for years) requirements. These are requirements that evolve rapidly (several times per year) and persistently (over the course of many years). In my experience, overly DRY code tends to present a large maintenance burden for projects with requirements like this. Whereas WET code can offer the flexibility needed to move fast.

    The main point is that there exist scenarios where it’s useful to question the DRY principle, and in no circumstance should either DRY or WET be taken to the extreme.

    1. 8

      Exactly. DRY is a principal with a goal to minimize maintenance cost, but it can be taken way overboard to where it’s counterproductive. The value you should be targeting is to minimize the cost of maintenance and change, not to make the code DRY or clean or anything else.

    2. 3

      Rather than the “rule of 2” (classic DRY) and the “rule of 3” (what this guy is proposing), have “the rule of N”, where N depends on ratio between the size of the duplicated code and the cognitive complexity of the abstraction.

      1. 3

        Or here’s a wild concept: try different programming methodologies and use what works best for you!

        1. 2

          I could swear this - or something very like it - has been posted here previously. Can’t find it on a search.

          1. 6

            I also remember a similar article, although the one I’m thinking of was more focused on data-oriented vs object-oriented programming. The same point was being made that you shouldn’t start to abstract things until you see it pop up at least a few times.

            1. 3

              Everyone posts this over and over again, and it doesn’t move very fast because people try to maintain WET projects and learn to DRY it up.

            2. 2

              At work, I have lots of suffering due to DRY absolutism, because we’re using Ruby and DRY is a holy dogma in rubyists’ culture. Every two remotely similar lines of code being extracted into methods with funny names, calls of methods being extracted to other methods, class fragments being extracted to mixins and superclasses. Page templates being cut to 2-3 lines and exploded into tens of files, sometimes with lots of variables and ifs inside.

              Trying to inline any of these things cause in “do you even have basic experience in software design?” reaction in code review, because “functions are designed to deduplicate code fragments”, despite any of refactoring books and even beginner articles mention that when you have bad abstraction you’re better to have duplication instead.

              1. 4

                There’s also the “self-documenting code” dogma in which, rather than a simple readable method with straight-down flow and a few comments to explain what’s happening, you break the method into 5 other methods with “self-documenting names”. Now you have to jump around the code 10 times to understand it. Oh, and the code style guideline makes you alphabetize the methods so the flow is hopelessly scrambled and the methods aren’t even on the same screen!

                1. 1

                  We have compiler hints to inline code, but no editor support for that, funny huh?

                  Vscode (and I imagine visual studio) have a “peek” feature, but I imagine something with even less friction might be useful too.

                  1. 1

                    I’ve heard the argument against jumping around code many times before, and I just don’t get it. Would you mind explaining to me what it is that annoys you about it? I jump to definition then jump back to where I was. In my mind it’s identical to following a hyperlink instead of embedding it right there and then.

                    FWIW, I fully agree with self-documenting code. If a comment explains what a block of code does, turn the comment into a function name.

                    1. 1

                      Well, [6] down [4] don’t you [2]

                      1: extreme

                      2: find it [5] [3]?

                      3: follow

                      4: to an [1]

                      5: hard to

                      6: if you take it

                      1. 2

                        Except code doesn’t look like that. Functions aren’t named after numbers, are they?

                        1. 1

                          We’re talking about jumping around…naming is a whole other barrel of monkeys.

                          1. 2

                            To me, there were two problems with your example: silly names and weird structure. Code doesn’t have that structure either.

                            I also don’t think naming is another barrel of monkeys whatsoever: I don’t know what a function called two does, but I can guess what one called send does. I usually don’t need to jump around in well-named code.

                            1. 1

                              I’m happy you haven’t seen code like this, but I have! Break a method into one-or-two line pieces, move them into methods with “self documenting” names (many of which, btw, are the functional equivalent of “add 1 to x” comments), then alphabetize them, and it’s very much a similar reading experience if you want to see what the actual flow is.

                              I think you may not appreciate that most of the methods I’m talking about in this style consist of a single Boolean expression taken out of an if statement, or something of similar size.

                  2. 3

                    Yikes, sorry you have to deal with that.

                    FWIW, I’d question whether they have much experience in software design and working with Ruby, because a lot of what you’re describing is really not representative of “rubyist culture” (to the extent that that’s any one thing). Sandy Metz is a huge advocate of “it’s better to have duplication than the wrong abstraction”.

                    Logic and a big proliferation of variables in templates is a huge yikes from me. A Presenter/Decorator layer has been the recommended solution to that for the better part of a decade, and there’s multiple popular gems out there that can be leveraged. DRY is great refactoring goal when you’ve identified multiple competing uses of common functionality that can drive the design of a small API to centralize that knowledge, but it’s not dogma and it stops being useful when it overly harms readability.

                    And condescending remarks in code reviews is always a huge red flag.

                    1. 2

                      I encountered the same dogmatic mentality on multiple unrelated Ruby projects so it feels like it’s part of culture. And yet, Ruby has one of the best communities around programming languages; it has healthy perfectionism and pedantry, but its dark side is dogmatism about DRY, following arbitrary metrics (i.e. no more than 5 lines per method) and “code should be self-documenting”.

                      1. 1

                        I guess we’ve just had different experiences. I’ve never worked anywhere that actually took the “5 lines per method” seriously. I’ve certainly run into those people on the internet, though, so I know they exist.

                  3. 1

                    Very off-topic, but author claims to be a “libertarian socialist” … how? I can’t think of two more opposite political stances.

                    Edit: I see that the author posted this! Very curious to hear your answer if you care to share :)

                    1. 5

                      Sure! Libertarian Socialism is a tried and true standing - its just that the modern day “libertarians” co-opted the word for their own gain. The Wiki page for this has some good info, but basically I believe in direct democracy, worker self-management in the workplace, and decentralized political organizations.

                      1. 2

                        Gotcha! Thanks for sharing.

                    2. 1

                      I don’t know. Too much abstraction is obviously bad, but I’ve yet to encounter a situation in which I DRYed something and regretted it. The amount of times I had duplication and regretted it however…