Discussion about this post

User's avatar
Mário Melo's avatar

Thanks for this post, Dave! Couldn’t agree more!

My latest post was pretty much about a similar experience. And that led me to a reflection:

If you are writing a test and need to write a mock, you probably missed an opportunity to do incremental development. Because that mock should already exist as your first implementation.

I’m still refining that idea, but right now I think it makes a lot of sense.

Expand full comment
Lorin Ricker's avatar

Dave -- My take-away from this great article is that "...there isn’t actually a duplication here at all, because DRY is about knowledge, not code." In my own learning to refactor, I've (too frequently) boxed myself in by taking the obvious application of DRY: "Hey, here are some repeated lines of code." It's only when we start understanding the value of having a single source of truth for each decision point (etc.) in the code that we can proceed to refactor... the right things (which might actually be a few lines of duplicated code). You have elaborated and explained this eloquently.

I advise, when asked, that high-level/abstracted programming languages -- like Ruby code -- is really primarily written for communication between people (for example, my teammates, or "my future self"), not for the computer. Indeed, in compiled languages, the compiler may optimize code by "unrolling loops" and other object-code level which actually re-introduce repetitions (of sequences of machine instructions), things which can really speed-up execution. So there's a whole lot'a difference between crafting well-designed code in Ruby (or even Pascal or C) vs. what goes on at machine execution time. That's a lot of what his eminence Prof. Knuth was writing about in the days of "Structured Programming without goto Statements"... and those were the heady days when we all were just getting a glimmering of what compiler optimization algorithms could actually do for runtimes. "Optimization" was another (academic) word for "tight code", which we all aspired to especially in assembler language. It took a while -- a few years, maybe a decade -- to really sort this all out and understand the consequences as we do today.

Repetition often helps clarify things in a natural/people language like English -- the mere occurrence of lines of repeated code should not, by itself, set off DRY-alarm-bells -- that's much more of a code smell thing. If the repetition, in the form of a few lines of repeated code in a clear context, serves the understanding (by a person), and especially if it clarifies a carefully thought-out design, then the urge to refactoring-on-autopilot needs to be tamped down a bit. And yes, these higher-level design considerations and decisions do lead to code which is easier to explain, evaluate, debate and understand, and then later to change, modify, correct and evolve if/when appropriate. Thanks!

Expand full comment

No posts