Live data from Hacker News

Hang your code out to DRY

johan.hal.se

31–40 of 82 posts

Re: Hang your code out to DRY

#31

I find it fascinating that people are so against inheritance/polymorphism, these days. That's one of the absolute best ways to DRY. factoring out common base classes is a classic OO exercise. It's possible to drastically reduce the size of a codebase, and the potential error exposure, by doing some simple extractions.

To me, inheritance and polymorphism are two different things. Polymorphism is about different units implementing an interface or equivalent protocol and that rocks. Inheritance is, essentially, dumping a bunch of code into your new class, and most of the time just imposes constraints and breaks API boundaries for no good reason. After studying and doing OOP for about 5 years, I don't see the advantages of inheritance…

Yeah; "favor composition over inheritance" remains good advice. "Classical" OO inheritance is brittle and often harmful.

Re: Hang your code out to DRY

#32

I really like WET (write everything twice). It also fits nicely with the rule of 3.

The problem I’ve seen with the “rule of 3” in real life is that by the time someone is writing a similar implementation by the third time, 5 years have passed and the entire team has rotated, so the programmer doesn’t have enough context to DRY anymore, and then the failed “big refactor that breaks corner cases” happens.

I find a mentality of _striving_ for DRY by default — even if end up choosing to duplicate for pragmatic reasons — to be beneficial in keeping programmers looking around for opportunities and refining the understanding of the context, with a better chance of incremental progress.

Re: Hang your code out to DRY

#33

Earlier quoted context omitted.

I wish I saved the source, but I saw somewhere the term: "Don't repeat concepts" While it doesn't spell out a word, I think it's much better advice than DRY, and better aligns with your heuristics.

Related tangent: "AHA" (Avoid Hasty Abstractions) is a decent counter to the over-application of DRY. IME, people reach for DRY too quickly, at the expense of other worthy but more subtle principles.

The opposite principle of DRY is WET. Write Everything Twice

Re: Hang your code out to DRY

#35
post #14
post #6

My first heuristic is: If I change the code in block A, is it assured that I will need to change the code in block B? My second heuristic is: Can I name the method I wish to de-duplicate in a way that is honest for all cases I wish to cover, yet explains its business purpose? The more it deviates from these heuristics, the more likely I am to duplicate the code in object oriented programming.

I use, and teach juniors basically the same rule as your first one. I phrase it a little differently though: "if something happened in the future that required a change to function A, would the same requirement apply to function B as well?" I think your second heuristic is valid but a little dangerous, because being good at naming functions is somewhat orthogonal to being good at maintaining code.

From my perspective, naming functions well is a key component of maintainable code.

However, in this case, I use it is an extension of the question "is this the same concept?" if it looks like useFloorWaxOrDessertTopping, it's a good clue that you may have the same lines of code but they are certainly not the same concept.

Re: Hang your code out to DRY

#36
> On re-reading Sandi’s original article it says kind of what I remember it saying, but it also… kinda doesn’t? There’s a lot more talk about programmers honoring the abstractions of elders who came before them

That's because the original article is so clearly about tearing down bad abstractions, but a large majority of programmers - based upon discussion about the article - seem to never get past the first part of it.

Given a long enough time horizon, all abstractions turn bad. The solution isn't to not abstract. The solution is to tear them down when they go bad. And if you don't learn to tear down bad abstractions, your codebase will devolve into shit regardless of what you do.

Re: Hang your code out to DRY

#37

Earlier quoted context omitted.

I wish I saved the source, but I saw somewhere the term: "Don't repeat concepts" While it doesn't spell out a word, I think it's much better advice than DRY, and better aligns with your heuristics.

That's actually more or less how DRY is described in The Pragmatic Programmer (20th anniversary edition): > Every piece of knowledge must have a single, unambiguous, authoritative representation within a system. Further on: > Dry is about the duplication of knowledge , of intent . It's about expressing the same thing in two different places, possibly in two totally different ways. [emphasis in original] And the next…

Early in my career, a co-worker and I developed the habit, when a bug was fixed, of asking each other "Did you fix it everywhere?"

But that's the problem right there. Why is there more than one place to fix it?

(Now, sure, if you're using a function call wrong, you need to fix it everywhere you call that function, and it's fine that there are multiple such places. That's what functions are for. But if it's something like how a value is calculated... why is there more than one place that calculates the value?)

Re: Hang your code out to DRY

#38

Earlier quoted context omitted.

I wish I saved the source, but I saw somewhere the term: "Don't repeat concepts" While it doesn't spell out a word, I think it's much better advice than DRY, and better aligns with your heuristics.

Exactly. I find it helps to also state that it doesn't mean "Don't Repeat Characters"

I've pointed out in the past that if the characters you're deduplicating don't actually have the same meaning, you're just compressing your code; I've been trying to popularize labelling that kind of aggressive misapplication of DRY "Huffman coding".

Re: Hang your code out to DRY

#39

Earlier quoted context omitted.

Related tangent: "AHA" (Avoid Hasty Abstractions) is a decent counter to the over-application of DRY. IME, people reach for DRY too quickly, at the expense of other worthy but more subtle principles.

The opposite principle of DRY is WET. Write Everything Twice

I think the old "remove duplication the third time you write it" is bad advice as well, to be honest.

First off, it excuses some really egregious behaviour like copying entire large chunks of code representing an identical concept just because "I haven't copied it twice yet". I've seen an entire controller and all related views copied wholesale because it needed to be placed in another area of the app (with identical visual and functional requirements)

Secondly, if the code is only incidentally identical, even 3 times isn't enough to say that you should apply DRY. 3 independent concepts that happen to currently share implementation still shouldn't be deduplicated. I think a great example of this is the inherited resources gem in rails that implements a "standard" interpretation of controller actions - which works well at first until your controllers need to do something other than basic CRUD. The fact that say, an update action handles parameters and saving in the same way as some other update action may currently be true, but is not at all guaranteed to be true in the future, even if you have 100 update actions in your app.

Re: Hang your code out to DRY

#40

I find it fascinating that people are so against inheritance/polymorphism, these days. That's one of the absolute best ways to DRY. factoring out common base classes is a classic OO exercise. It's possible to drastically reduce the size of a codebase, and the potential error exposure, by doing some simple extractions.

Base classes tend to limit what your abstractions are though. In practice I've found that while different classes share common behaviour, it's not always so straightforward that it can be arranged into a tree. A mixin type approach, where behaviours can be attached to different classes (particularly if those behaviours don't define any new state) works much better.
Post reply on HN