Functionally repetitive code is repetitive because of the functional nature of the activity being coded – for instance, finding a resource on a controller in all the RUD actions. That’s functionally repetitive. “Find the course” always means the same thing here.

Drying this code up makes things simpler only because “find the course” always means the same thing at a functional level.

Not all repetitive code is functionally repetitive though. This is especially true in view code for me in TroopTrack where I have lots of conditional code based on the type of organization the user is in. I end up with lots of code like this haml partial:

I don’t like this code much at all. All those conditionals based on the type of troop we are looking at makes it hard to read and to think about, but the first alternative I think of involves creating a different partial for relevant type of troop. We support seven different types of troops in TroopTrack, so the idea of potentially having seven different partials with big swaths of them being the same made me cringe a bit at first. But the more I work on TroopTrack, which is now in its sixth year, the more palatable the idea has become. I now think it’s better than what you see above, especially if I introduce some conventions to make it easier, such as including the troop type in the partial file name, like this:
– achieve_menu.bsa_troop.html.haml
– achieve_menu.bsa_pack.html.haml
– achieve_menu.scouts_au.html.haml
– achieve_menu.ahg.html.haml
…

That makes the intent extremely clear, and I could use interpolation to render the right partial with a single line of code.

To me, that code may be repetitive, but it’s a lot easier to reason about and to work on. DRYing it up, at least in the way I originally did it, only makes it worse. I think the reason DRYing it up isn’t helpful is because this code is only repetitive by COINCIDENCE. By this, I mean that the features that are common are not common due to something functionally intrinsic about them, but just because they happen to share some common needs.

I mentioned this realization to @kofno and here is what he said. I like his perspective:

I think you’re having an important realization about the intent of DRY. It’ s not about repetitive code, but it’s about having a single canonical place for some piece of system information.
Whether that is how to render users, or what makes a valid course, etc.
Drying up things that change together is what’s important.
If you try to dry things that are orthogonal but only look similar, you’ll be miserable.
For removing repeating code patterns and getting rid of boilerplate, that’s what macros are for (provided your language supports them). Ruby kinda does w/ metaprogramming.

Like @kofno, you might have had a “well duh” reaction to all this. That’s cool. I’m learning…