Live data from Hacker News

Prefer duplication over the wrong abstraction (2016)

sandimetz.com

151–160 of 375 posts

Re: Prefer duplication over the wrong abstraction (2016)

#151

I used to struggle with abstractions back in my OOP days but since moving pretty much to a purely functional approach I find that code duplication is rare. Just have a function and call it in two parts. The main abstraction issue is then data structures but with TypeScript interfaces being duck typing essentially I run into few problems there as well. So code duplication because of abstraction issues is rare. Code du…

Developers do not really have to be siloed to experience code duplication. When the team size grows past a certain point such that each person is not aware of what every one else is working on, code duplication is quite inevitable. This is the case even if everyone writes functional style code. In fact this just happened last month at work: I wrote a new functional and pure helper function and placed it at the beginning of the file; a week later a colleague told me a similar helper function with substantially the same functionality with a different signature had been written and placed near the end of the same file.

Re: Prefer duplication over the wrong abstraction (2016)

#152
post #63
post #47

Earlier quoted context omitted.

Hardly iconoclastic, it's a very sensible suggestion. It would be iconoclastic if the common sense basic approach would be to start with abstraction. It's not, the common sense default is to write possibly duplicate behavior until you actually discover several cases to abstract away, until you bevalop a sensible idea of which functionality unites them and which doesn't carry over all of them. > Once you have an awkwa…

> Maintaining the wrong abstraction, or, god help, abstractions, would be even worse. Hard disagree. When you've had to chase through a change in untold and actually unknown numbers of duplications of code in different permutations and fix them because they are all on fire simultaneously, you'd disagree too. A bad abstraction would at least have had one fire in one place.

> A bad abstraction would at least have had one fire in one place

That's true only for "good" abstractions. Bad abstractions will often require you to change code in all the places using it, requiring you to understand how all of them work and what are their requirements, _all at the same time_.

Re: Prefer duplication over the wrong abstraction (2016)

#153
post #16
post #6

This is the biggest lesson I got from LMMs. I have a 1 million LOC vibe coded project that I can only imagine would fit in a few hundred thousand lines. But it's still holding up, I expected some kind of development collapse long before this point.

Well sooner or later I would expect a developer who intimately understands their code base to feel compelled to start refactoring and extracting fitting, meaningful well-leveraged abstractions.

I don't think that will happen anytime soon. Prompts are the code now, and programming languages code is compilation product. Almost nobody optimizes compiled assembly code.

Perhaps "recompilation" - rewrite by replaying all prompts in strict code quality context (linters, complexity & dedup checks) would make better abstractions.

The only problem now is that LLMs are non-deterministic.

Re: Prefer duplication over the wrong abstraction (2016)

#154
post #68

Too many abstractions are bad. Too many code duplication is bad. Part of being a good engineer is finding the right balance. I know engineers who would gladly duplicate code all over the code base to avoid creating a new abstraction. I know engineers who create polymorphic abstractions for a single caller with a very obvious set of parameters. So much of wisdom is in finding balance and not being dogmatic about rules…

I feel like the balance has shifted over the last 30 years, and is speeding up. Semi-automatic and fully automatic re-factoring has made dealing with duplicated code much faster, cheaper and safer. Changing abstraction is still high risk.

Isn't it the opposite?

Automated re-factoring means you can refactor duplicated code only as long as it is exactly duplicate.

Whereas the whole problem is that when somebody changes 3 out of 10 of the duplicate cases in a simple way that they are no longer exactly duplicate, and then somebody fixes a bug in one of the other 7/10 cases, they can update the bug across the 7 "duplicate" cases but they'll miss the 3 that aren't.

The problem with duplicate code is always when some of the instances get changed/fixed but not all of them. And that when somebody edits one instance, they often aren't even aware of all the other instances.

Abstractions are low-risk, because you know where the code is. If it's the wrong abstraction, you can fix that and know what you're fixing. Whereas with duplicated-yet-modified code, you've now lost the connections between them.

Re: Prefer duplication over the wrong abstraction (2016)

#155
post #16

Earlier quoted context omitted.

Well sooner or later I would expect a developer who intimately understands their code base to feel compelled to start refactoring and extracting fitting, meaningful well-leveraged abstractions.

I don't think that will happen anytime soon. Prompts are the code now, and programming languages code is compilation product. Almost nobody optimizes compiled assembly code. Perhaps "recompilation" - rewrite by replaying all prompts in strict code quality context (linters, complexity & dedup checks) would make better abstractions. The only problem now is that LLMs are non-deterministic.

> Almost nobody optimizes compiled assembly code.

Compiled assembly code is not an input to the next compilation; source code is an input to the LLM's next inference.

Sure, maybe "prompts are the code," but you must realize that code is also the prompt.

Re: Prefer duplication over the wrong abstraction (2016)

#156
I always try to design in a way, that using abstractions/shared logic is optional.

I've worked in too many projects, where every new feature needs to be built on top of existing abstractions, that often lead to severe restrictions if something slightly different is required. I always try to create reusable units/components, that can either be used as intended or replaced by something that behaves slightly different if needed.

Components are not necessarily frontend components, this extends also to backend logic.

Re: Prefer duplication over the wrong abstraction (2016)

#157
post #126

Earlier quoted context omitted.

> instead it would spread its assumptions to different parts of the system, But so does duplication, in practice, and it diverges more as it does.

Duplication is just code doing the same thing in several places, and as such it's much easier to make DRY (and much easier after you have N copies to see what should be shared and what should not), compared to re-architecting the whole system to remove a bad abstraction.

No. The duplication is seldomly that clean. It has started to diverge in subtle ways where the question becomes whether that was the intention or not. In the worst possible cases it has resulted in 8000-line functions full of duplication. 're-architecting the whole system to remove a bad abstraction' sounds fear mongering. That never happens.

Re: Prefer duplication over the wrong abstraction (2016)

#158

Too many abstractions are bad. Too many code duplication is bad. Part of being a good engineer is finding the right balance. I know engineers who would gladly duplicate code all over the code base to avoid creating a new abstraction. I know engineers who create polymorphic abstractions for a single caller with a very obvious set of parameters. So much of wisdom is in finding balance and not being dogmatic about rules…

Duplication is often less harmful than abstraction.

Duplications can often be cleaned up over time, bad abstractions can quickly become a bottleneck, that severely slow down everyone working on the project.

Re: Prefer duplication over the wrong abstraction (2016)

#159
post #25

No it's not. This has always been a needlessly iconoclastic rather than sensible suggestion. At the very least it is not once you're working at the wrong kind of scale. Once you have an awkward number of customers (more than five and less than a hundred), maintaining duplicated code that should have been abstracted and modularised will only seem cheap if you don't mind that you burn through even junior employees at a…

100% agree. 'Code duplication is far cheaper than the wrong abstraction' is a very good candidate for the worst programming article ever.

Re: Prefer duplication over the wrong abstraction (2016)

#160
post #63
post #47

Earlier quoted context omitted.

Hardly iconoclastic, it's a very sensible suggestion. It would be iconoclastic if the common sense basic approach would be to start with abstraction. It's not, the common sense default is to write possibly duplicate behavior until you actually discover several cases to abstract away, until you bevalop a sensible idea of which functionality unites them and which doesn't carry over all of them. > Once you have an awkwa…

> Maintaining the wrong abstraction, or, god help, abstractions, would be even worse. Hard disagree. When you've had to chase through a change in untold and actually unknown numbers of duplications of code in different permutations and fix them because they are all on fire simultaneously, you'd disagree too. A bad abstraction would at least have had one fire in one place.

> Hard disagree. When you've had to chase through a change in untold and actually unknown numbers of duplications of code in different permutations and fix them because they are all on fire simultaneously, you'd disagree too.

The other end of this spectrum is dealing with the architecture astronaut's up-front abstraction. Totally overengineered for solving the initial requirements, but then constantly needing new hacks to make it cope with new requirements as they come up in the normal course of work.

That's why there's a balance in there, it's somewhere between "always duplicate code even when you know a lot about the problem" and "always write abstractions even when you know very little about the problem."

Post reply on HN