I’ve watched DRY get applied as a reflex more than as a rule. Two similar lines appear and a helper is extracted, and six months later that helper is a flag for every caller and a name that no longer covers any of them. The failure isn’t that the team deduplicated. It’s that they deduplicated on appearance and skipped the second sentence Hunt and Thomas wrote, the one with the word knowledge in it.

Code that looks alike isn’t necessarily the same fact. Two loops that happen to iterate the same way for different reasons are two facts. Merge them and the next change to one becomes a change to both, which is exactly the rot DRY exists to stop. The test I use is whether the two copies would have to change together. If they would, they’re one fact. If they wouldn’t, they’re two facts that currently rhyme.

The boundary matters as much as the count. Inside a bounded context, deduplication is cheap insurance, because both copies answer to the same owner and the same change. Across a context boundary, a shared helper fuses two products into a single change, and now every team that touches one has to think about the other. The coupling costs more than the duplication did.

So I extract on the second occurrence inside a context. A little copied code is cheaper than a helper with a name that means three things.

Fair to the reflex: the reflex exists because duplicated knowledge really does rot, and neglected copies drift until there’s no way to tell which is right. The rule is sound. The trigger is wrong.

The full write-up is at https://prickles.org/tenet/dont-repeat-yourself/F3

  • degen@midwest.social
    link
    fedilink
    English
    arrow-up
    4
    ·
    20 hours ago

    Don’t Reuse Yeverything

    Basically, don’t let one ideal (dry) encroach on another (low coupling)

  • Homosexual sapiens@lemmy.blahaj.zone
    link
    fedilink
    arrow-up
    1
    ·
    17 hours ago

    Wow, the structure of that article is infuriating to me as a reader. And the site keeps thinking that my horizontal scrolling in the code views means I want to swipe to a different article.

  • anamethatisnt@sopuli.xyz
    link
    fedilink
    arrow-up
    3
    ·
    22 hours ago

    Hunt and Thomas

    Authors of The Pragmatic Programmer which has many tips and concepts, including the DRY principle which states that “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system”.

    Doesn’t help me understand OP fully, but makes me understand the context a bit.

  • Marcela (she/her)@lemmy.blahaj.zone
    link
    fedilink
    arrow-up
    2
    ·
    20 hours ago

    Another principle is “don’t optimize code prematurely”. This means that first you make it work, then you optimize it.

    It is easy to fool yourself with the DRY principle if you haven’t the big picture available.

    If you only need the helper twice, it is noise.

    If you create abstractions you have to look them up each time (instead of just using a language you are fluent in), then it is even worse than noise. An obstacle.

  • Riskable@programming.dev
    link
    fedilink
    English
    arrow-up
    2
    ·
    edit-2
    21 hours ago

    As time goes on I feel like the concept of DRY has more applicability to compiled languages like C/C++ and Rust than interpreted ones.

    From a concise coding standpoint, it’s a great idea most of the time. However—having worked with some long-term projects—I’ve found that it can create “code smells” if it’s taken a little too seriously.

    For example, I’ll often see loads of tiny (Python) functions that do simple things like applying a regex. Then I’ll search the code and see that a single regex function gets called in just two places.

    If that was the only time it happened, it wouldn’t be a big deal. Except I’ll see dozens of tiny functions like this at the top of many modules and be scratching my head wondering why they went to such an extreme. It makes my job as a reviewer harder because now I have to scroll all the way to the top of the script and back constantly to figure out WTF it’s doing.

    Not only that, but Python doesn’t have a JIT that would optimize away those extra functions calls. Every function call in Python carries some overhead (both CPU and memory), so by dividing up your functions into dozens of little ones you’re actually slowing it down.

    Normally such slowdowns are so trivial it doesn’t matter. But when someone is following DRY like some kind of religious extremist, those extra calls really can and do add up. Especially when you find them being called inside of deeply nested loops!