Hacker News new | ask | show | jobs
by wcarss 70 days ago
I agree with what you're saying about writing something twice or even three times to really understand it but I think you might have misunderstood the WET idea: as I understand it, it's meant in opposition to DRY, in the sense of "allow a second copy of the same code", and then when you need a third copy, start to consider introducing an abstraction, rather than religiously avoiding repeated code.
1 comments

Personally, even for a prototype, I'd be using functions immediately as soon as I saw (or anticipated) I needed to do same thing twice - mainly so that if I want to change it later there is one place to change, not many. It's the same for production code of course, but when prototyping the code structure may be quite fluid and you want to keep making changes easy, not have to remember to update multiple copies of the same code.

I'm really talking about manually writing code, but the same would apply for AI written code. Having a single place to update when something needs changing is always going to be less error prone.

The major concession I make to modularity when developing a prototype is often to put everything into a single source file to make it fast to iteratively refactor etc rather than split it up into modules.

> mainly so that if I want to change it later there is one place to change, not many

But what happens when new requirements come in for just one of the things? If you left them separate, it's an easy change of a few lines. If you created an abstraction, now you either have to add a bunch of if statements, or spend time undoing the entire abstraction that you spent X amount of time creating.

If a bunch of other code has built up around that abstraction, undoing it can become a serious chore. I've worked on apps that had way too many premature abstractions, and we just had to live with it because it would be too risky and onerous to try to undo them.

In my experience, it's generally an order of magnitude easier to add an abstraction to a mature app when you get tired of making changes in multiple places, than to remove one when the app evolves and you realize these things aren't actually that similar. Also when you wait to abstract, you might see a better way to do it, or how to reduce the scope so that you're using composition to share a bunch of smaller pieces vs. sharing the entire page/object/interface/endpoint/etc.

Obviously, this isn't a blanket rule. There's an aspect of soothsaying to guess which things might diverge and which are likely to spawn a lot more similar copies.

> But what happens when new requirements come in for just one of the things?

I guess it could happen, but that depends on your mental model when coding - if you're just pattern matching similar chunks of code (which are not being used in a semantically identical way) then all bets are off, although that seems a very alien concept of how someone might code.

OTOH, if you have a higher level mental model of what you are doing then it's not a matter of "this looks like common code" but rather "i need to do the exact same operation" (same inputs/outputs/semantics) here. Maybe I'm expressing it poorly, but I can't recall ever having to fork a function because requirements at two call sites just diverged.

The danger with people that claims to follow DRY is that they don’t check first that they are repeating yourself. As soon as they’re encounter similarity, they assume equality and rush to abstract it. But if one knows the domain enough to know that some logic is the same, not just similar, then no need to write it twice first.