3

We have all heard of Don't Repeat Yourself and Write Everything Twice, but I've never understood why anyone would prefer the latter of those. Obviously you can go overkill with DRY, with the code ending up unreadable and hard to debug. But why would you want to strive to write more code than is required to perform a task? Isn't it always more preferable to have DRY code than WET code?

Maybe I just don't understand the Write Everything Twice idiom. What is meant by it?

4
  • 6
    There is no "Write Everything Twice" idiom; nobody does that. You're confusing a principle with pragmatism. Apr 8, 2021 at 13:21
  • 3
    You've essentially answered the question already - other important principles such as KISS, YAGNI and JFDI tend to get priority over DRY. Apr 8, 2021 at 13:22
  • 2
    Related to this - I once worked at an organisation where some of the most profitable contracts with customers included requiring source code (99% identical to the code used for other customers) to be kept in an isolated branch in SVN - no reuse at all between that customer's branch and our main trunk without their explicit permission (not even bug fixes). By far the worst violation of DRY I've ever seen, but we were legally bound to keep it that way; technically it was very poor, however the hugely increased fees charged to those customers helped keep the business afloat. Apr 8, 2021 at 13:39
  • this question is discussed at meta
    – gnat
    Apr 8, 2021 at 19:22

5 Answers 5

17

No one is really promoting unnecessary code duplication. You don't usually have a choice between orthogonal (DRY) and duplicate (WET) code. “WET” is a bit of a strawman for DRY-proponents to argue against. But most code gets messy and non-orthogonal over time, without any intention to make it worse. Kind of like the second law of thermodynamics applied to software maintainability: entropy/chaos increases. Thus, it needs conscious effort to make and keep code maintainable.

However, you will find many people that argue against DRY. Overly literal application of DRY principles leads to code that has no duplication, and lots of abstraction. However, the wrong abstraction can be more problematic than no abstraction at all. Some things look like duplication because they merely happen to appear the same, not because they are fundamentally and necessarily always the same. E.g. if I factor out two pieces of code that currently are the same but have nothing to do with each other, I'll have caused unnecessary coupling. If I then change that refactored code, I'll have caused changes in two unrelated places – making the system more difficult to debug and maintain. In this viewpoint, it might be better to hold off from creating abstractions unless you have a better idea of what a good abstraction could look like. That insight often requires that you've spelled out a few instances of the non-abstracted, duplicative version.

5

The name itself is a joke, but it is just an alternative name for the well known Rule of Three, which states that the third time you encounter a certain pattern, you abstract it into some reusable unit.

It is a question of balancing simplicity against conciseness. When code is extracted into a function to conform to DRY, you create an abstraction. But abstraction have a cost - using the wrong abstractions may increase complexity and make maintenance harder. So abstractions should not be created willy-nilly to save a few lines of code. The "rule of three" (or WET) basically says think twice before creating an abstraction.

2

In my view, the principal reason why people Write Things Twice is shortsightedness.

Software 'engineering' is in many ways a much less structured activity than real engineering, but it does share an important property with highway or utility engineering: almost every decision you make involves a trade-off between two mutually incompatible goals (e.g. cost vs. reliability, strength vs. completion time, etc.)

Since writing software is a more abstract task than erecting a bridge, our trade-offs tend to be more abstract than the obvious ones that you can measure with your wallet and your calendar. Very often, copy&paste of a piece of codes that is known-good allows you to achieve one particular task with great speed and low risk. The trade-off here is that of a plus in immediate speed of achievement of one task against a slight minus in the maintainability of the entire code base. Because the minus is hypothetical and lies in the future, it is very easy to overlook it altogether and assume that it is negligible.

In general, I believe that if people had a proper grasp of the entirety of the project to which they contribute, they would see that copy&pasting code is a net minus. But as long as a contributor measures his success only by how fast the task at hand was completed, it can look very much like a plus. Understanding this requires long personal experience, or more faith into colleagues with more experience than the typical junior programmer can muster.

2
  • 4
    There is an additional benefit of copy/paste, and that is that it decouples. If I'm writing a module and I want it to run independently, I can copy/paste code instead of putting it into a central library and creating a new dependency. Also, a separate copy means I can modify one copy without affecting the other. So there are legitimate reasons for being wet. Apr 8, 2021 at 13:25
  • 5
    I would argue that this is not WET, and not a violation of DRY. If it's an independent module that evolves independently, then it was never a duplicate in the first place. A typical example, reduced almost to the point of absurdity, is when someone creates a single constant for sales tax and drinking age because both happen to be 18, and you need to remove that duplication. It was never duplication in the first place, because the two 18s mean different things. Apr 8, 2021 at 16:04
2

WET is a word of caution against DRY. In many cases writing "duplicate" code is better because the code is actually different and will change separately. The two bad things that tend to happen when being overly dry is have a lot of functions that don't actually end up getting reused and just cause extra cognitive overhead for no real gain, or you have a method that is reused heavily but ends up with multiple execution paths for each different use. If you write everything twice, then you don't end up with extra methods and you don't end up combining things you thought were the same but ended up not being the same. The downside of WET is that when you go to write something a third time you should be combining at that point, but this fails in larger code bases because you may not know it's been written many times.

0

I think you're really asking about WET source code.  But you more generally wrote "WET code" without qualification as to source vs. other.

WET code may be more performant as it can be customized for the exact situation.  This approach is particularly appropriate when generating code, whether that is machine code or high level language code.  The generator already provides abstraction so that the generator source, whatever form it takes, is more DRY, so there's little need to have the generated code be as DRY or seek increased abstraction.

For example, a compiler may inline methods — this is literally copying/repeating the same code in different places (in the generated code).  Each copy can be optimized to take advantage of surrounding circumstances, while the original source code has the method implementation in only one place.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.