Live data from Hacker News

Prefer duplication over the wrong abstraction (2016)

sandimetz.com

71–80 of 375 posts

Re: Prefer duplication over the wrong abstraction (2016)

#71
post #21

Yes. I’m dealing with a graphql, urql, Next, Prisma stack at the moment. Something that would be a handful of lines of code in a different stack ends up being hundreds in this one. The Node ecosystem is full of wrong abstractions.

The problem is self-inflicted. You do not need to keep jumping to the next trendy framework.

my paycheck needs me to.

Re: Prefer duplication over the wrong abstraction (2016)

#73
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.

It's made me wonder the same, but most LLM generated codebases haven't been around long enough to judge maintainability. I have noticed issues in some of my more LLM heavy code when I expect a change to be replicated in multiple areas, assuming common code / styling was reused, only to find it wasn't. It's for that reason I can't use LLMs for client codebases without heavy scrutiny of every line generated (for my own hobby projects I'm a lot more lenient)

Re: Prefer duplication over the wrong abstraction (2016)

#74
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…

> I would go as far as to say that any abstraction you can maintain (that is in active maintenance, I mean) is better than code duplication once you are passed a de minimis threshold. Pretty much everyone arguing for duplication has argued what you are saying, which is wait to see a few instances of it before committing to an abstraction. No one is saying duplicate everything 100 times. So I don't think this discussi…

The point is it sounds all smart and sophisticated and principled in the abstract environment of a code discussion in a blog post.

In the real world, duplication happens in an emergent way, there isn't the time each time to judge whether it's really time to just quietly abstract that code, you may not get the permission, budget or window to do it, and if you don't stop the rot really early you are locked into the pattern.

Re: Prefer duplication over the wrong abstraction (2016)

#75
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.

Changing abstraction is a high risk unlike agents refactoring scores of almost identical code.

Re: Prefer duplication over the wrong abstraction (2016)

#76

Two talks come to mind here: Mike Acton's Data-Oriented Design and C++ [1] and Brian Cantrill's The Complexity of Simplicity [2]. Mike's talk argues that code solutions need not be modelled on the real world, and that different data creates different problems, which need different solutions. I can't do the talk justice, but it's had a big impact on me. Brian's talk is about abstraction generally, and how it's difficu…

> Mike's talk argues that code solutions need not be modelled on the real world, and that different data creates different problems, which need different solutions.

I've always found it odd when even fairly smart engineers sometimes prioritize real-world metaphors over the actual needs of the codebase. Years ago when I was only a few years out of school, I was implementing a connection pool in Rust, and the most reasonable way to implement it was to have the connection hold a weak reference to the pool so that it could get checked back in automatically when dropped. My manager (an extremely experienced engineer) didn't like this idea because "a library holds library books, not the other way around". I didn't feel like this was a compelling reason to design things differently, but he refused to engage with the issue in any way other than through the lens of that metaphor. Eventually the impasse was solved by one of the other managers in my department suggested that while library books don't contain libraries, they do have the name of the library stamped in the back as a reference to where they should be returned, and I guess my manager found this to be a reasonable extension of the analogy. If I were more experienced, maybe I would have recognized that I could find a way to engage with the analogy like the other manager did without ceding the point, but even today I still feel that it was completely bizarre to insist on that as the canonical way to frame things rather than just considering the ramifications of the abstraction in the code and the experience of using the library based on it.

Re: Prefer duplication over the wrong abstraction (2016)

#77
post #38

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…

what exactly is 'calling a function in two parts'

I believe they’re referring to callbacks / dependency injection / higher order functions to customize the behavior of a function?

Re: Prefer duplication over the wrong abstraction (2016)

#78
post #43

I once had to work with a system that was refactored and abstracted away heavily to use Redux. It didn't work then, the implementation had way too many abstractions, doing any change meant you had to touch dozens of files. It was insanity. Left me with a bitter taste regarding the redux pattern for ever (probably not the pattern's fault).

Over-abstraction is as much of a problem as under-abstraction. If the abstraction isn’t improving your ability to produce good code, it’s a bad abstraction. I’ve worked with a lot of abstraction patterns in a lot of languages over the 30 years of my career. Any of them can be good or bad. Unthinkingly applying them is always a problem.

Unsurprisingly, that goes for just about any idea in software development. I worked in one code base that heard small functions are best, so every function was less than three lines long. You don’t gain anything by replacing `lst.get(0)` with `get_first_item_in_list(lst)` (in fact, understanding becomes much more difficult), but breaking down functions into the smallest units that make sense independently within the business domain can be very helpful, both for understanding and testing.

Re: Prefer duplication over the wrong abstraction (2016)

#80
I prefer the go mantra: a little copying is better than a little dependency.

Abstraction is a vague term when used here. Is a shared function an “abstraction”? It’s more like implementation hiding, maybe some data hiding. But you definitely have a dependency on it now.

Acronyms like DRY are for beginners. Once you get good you know when to break the “rules” (and when not to).

Post reply on HN