DRY - Why?



Another software acronym people really seem to enjoy is DRY - Don't Repeat Yourself. As usual, the best way to understand it is to learn basic computer programming, then think "DRY is a less-than-useful way to restate what I already know." But it's popular, so let's look at it.

The original version makes more sense: a piece of knowledge should be in only one place. My simplification, which I like better than DRY is: share instead of copy. There's nothing complex why this is the way to do it. Inevitably the "piece of knowledge" needs to change, and copies can get out-of-synch. Early on when we learn programming we see versions of this, and the fixes for it:

Often we re-use a number. This code uses a margin of 0.15 in two places. If the margin changes, those 0.15's don't exactly jump out at us:

xPos = 0.15 + c*6; // measuring from left side
useableWidth = width - 0.15*2; // count both margins

Early on we learn to fix that by turning constants into constant variables. Or, as some people put it "never hard-code anything":

const X_SIDE_GAP = 0.15; // the one place "knowledge" of the margin occurs
xPos = X_SIDE_GAP * c*6; // self-documenting

When we teach that, we explain it as a positive (rather than the negative "don't repeat"): it's now easy to change the margin size. We also explain it as self-documenting code. In other words, we don't use this as an example of some other trick - using constant variables is the trick.

Another early "in one place" we learn is writing basic functions. At first we tell you they help organize the code. Even if we only call resetShape() once, it looks nicer as a function than as lines jammed into our 8-page init(). But later we explain how multiple people will be calling it. When everyone shares a function it guarantees they're all doing it the same way.

But functions are also about abstraction. We don't care how resetShape() resets, what it resets to, or whether it may change. That's all hidden, and we're glad it is. Functions are the trick, and not-repeating-code is merely one of the advantages.

Early structs are another not-repeating-ourselves use. The standard example has us use a group of variables to do something, then shows how turning them into a class can reduce typing:

// informal Dots with groups of variables:
double x1, y1, radius1,  x2, y2, radius2; // variables for 2 dots

// as a class:
struct Dot { double x, y, radius };

Dot d1, d2;

In a sense, we're no longer repeating "these 3 variables count as 1 Dot". But classes are also about creating a new type. Dot d1; is descriptive, and the compiler can use it to give better errors.

A common intro to arrays has us doing something to each of several variables, then again with a much nicer array loop:

int a0, a1, a2, a3, a4; // a non-array array
if(a0>10) a0=10; // yikes
if(a1>10) a1=10;
// better using the magic of arrays:
int A[5];
for i index in A { if(A[i]>10) A[i]=10; } // "can't be more than 10" only written once

As before, an array helps us avoid repeating lines, but it does so much more. List of ints is a useful type, and can grow and shrink.

So "one piece of info in one place" is an interesting observation, but where would we want to explicitly use it? At what point is "remember DRY" a useful thing to think? I say, nowhere.

As I noted, when we're teaching functions, structs, arrays and constants we talk-up how they save us from all that copying. But other stuff too, and I don't think linking them through DRY is helpful - saying "named constants help us with DRY, which we've previously seen in functions". Worse, to even do that we'd have to explain DRY early on, using abstract terms since we don't know any programming yet.

DRY also doesn't seem useful for writing real programs. We all ready think in terms of functions, structs and classes - "this is a good thing to turn into a function" and so on. Adding "also be sure not to repeat any piece of knowledge" won't remind us to do anything we weren't going to do anyway.

What bugs me the most is how non-DRY code is called WET. In logic class, Computer Scientists learn that if you don't always brush your teeth, it mean you skipped at least once, not that you never brush them. It's the difference between "opposite" and simply "not" (if you've taken the class, it's how "not All x" is the same as "there exists not x"). Anyone with this training knows not to jump to the opposite. Code that isn't dry should be called DAMP or MOIST.



Comments. or email adminATtaxesforcatses.com