5 ms·
> The underlying issue is the fear of change and the sunk cost fallacy of already written code. If you have the wrong abstraction, you can change it. It's not
by kajecounterhack 3y ago
> The underlying issue is the fear of change and the sunk cost fallacy of already written code. If you have the wrong abstraction, you can change it.
It's not that trivial. Consider that the wrong abstraction is reflected into your API (common), and consider that your API has many users. You are stuck with it, or you have to convince multiple teams (or, god forbid, external customers) to migrate to a better API. This can constitute a humongous waste of SWE-hours ($$$$$) and take quarters to accomplish, assuming you can get any buy in.
I think it comes down to what your organization looks like and how many users are going to be touching your code. If your abstraction is just for yourself internally and everyone else is not allowed to touch it, then fine. You will own the tech debt if the abstraction is wrong. If your abstraction has other users at your company, or external customers, it had better be the right one or at least an unavoidable stepping stone.
> If you created too much duplication, you can remove it.
This is actually true. Refactoring duplicated logic is a lot easier than fixing bad abstractions.
- wvenable 3y agoIt is that trivial. There is no alternative. You either have an API or you don't and you either change it or you don't. Hand wringing over the potential of making a mistake is a waste of time and effort. You will make a mistake. You will never get it perfect. You just have to deal with it. > Refactoring duplicated logic is a lot easier than fixing bad abstractions. Then you've just created an abstraction with all that potential to be bad sometime in the future.
- mcpeepants 3y ago> Then you've just created an abstraction with all that potential to be bad sometime in the future. I would argue that you've then created an abstraction, but with all the hindsight allowing you to create the _correct_ abstraction (or at least a much better chance at it approaching "correct")
- kajecounterhack 3y ago> It is that trivial. > You will make a mistake. You will never get it perfect. You just have to deal with it. These two comments sound at odds. First statement says it's easy. Second statement says it's hard. We can agree that hard things don't get solved without iterating. But a productive response to abstraction (which is really API design) being hard is not to say "stop handwringing, just do it." Instead, you can employ various strategies such as preferring experienced people to do it, making sure they did a good job of gathering requirements and considered the risks of their approach, spending time testing customer/developer ergonomics, etc. You can also defer producing an abstraction until your system is a bit larger and the duplication is becoming too much to handle, since you have a larger sample size of potential uses for your abstraction to help you converge on the correct API. Good abstractions can be the difference between success and failure, between organizational velocity and technical debt quagmire. Saying "we should always build abstractions" when it's difficult to build them correctly in one go sounds totally wrong on its face.
- wvenable 3y agoTrivial doesn't mean easy; it's means unimportant. And in this case I'm referring to the whole idea of abstraction or not. You're going to do it. You should do it. Sometimes you have to do it. Discussing it is pointless. Just move on to the how. > Saying "we should always build abstractions" when it's difficult to build them correctly in one go sounds totally wrong on its face. If you don't do that first "one go" how do get around to right abstraction? You're telling me you wouldn't use any intuition, planning, or thinking to build that first wrong abstraction? It seems above you just described how to do exactly that. Just writing without any abstraction in mind at all is just a huge waste of time. The only time it's painful is when you decide that you can't change anything you've done. But doing no abstraction is just as painful -- you just pay for it differently.
- kajecounterhack 3y agoOkay Mr. English, trivial may be defined as unimportant / trifling but if you're gonna label something like that then you have you consider why you're calling it unimportant. Still seems you're saying it's cheap, easy, and undoable. It's not. Abstraction building is _consequential_. > If you don't do that first "one go" how do get around to right abstraction? Right back at you: how do you get the data about how to build your abstraction without first living without one to understand what parts of the system should be abstracted? Starting with the abstraction and assuming you can fix it later is a luxury for overstaffed teams and people working on systems that nobody actually uses. You do realize, abstractions incur mental load on your users? Have you ever tried to use internal tools built ostensibly for your use case, only to find that it's taking more time and effort than if you lived without one? It's happened to me so many times, and the consequence of adopting a shitty abstraction has burned me so many times personally that I'm gravely aware of the downsides. Consider a streaming data tool that stupidly allowed users to put arbitrary data in a string field, which became abused for purposes it shouldn't have been used for -- now it's critical to the company and would take a YEAR of dev resources to retire, all the while being an endless source of headache and P0 SRE escalations. Consider an ML evaluation tool that requires you to understand how a bunch of leaky abstractions nest together. When you finally figure out how it works and it does 1 thing for you (generate P/R curves), it becomes extremely difficult to modify or debug without again understanding these horrible abstractions. Once you've spent a full quarter adopting it, you wish your team had just written something custom-but-maintainble instead of trying to get shoehorned into a tool that clearly wasn't thinking about you, and whose owners have left the company leaving you to absorb the cost. > But doing no abstraction is just as painful -- you just pay for it differently. It's less painful in the long run: doing no abstraction to start is often the right path. People often overrate the benefits of abstraction and underrate the clarity of repetition, especially when the repetition is trivial.
- Kapura 3y ago100% agree, especially about refactoring duplicated logic. Super-duplicated code begs to be refactored, and having many examples of the same functionality helps you build an API that is robust without adding "what-if" functionality to try to futureproof code (impossible).
- coliveira 3y agoMigrating to better APIs is done all the time. It is not an issue worth discussing about anymore. But even if you have to maintain an API this doesn't mean you cannot change the underlying implementation.
- simonw 3y agoIt absolutely is an issue worth discussing, any time you are maintaining a library with more than a few other people using it. Breaking backwards compatibility in a library with hundreds or thousands of users is not something to be taken lightly!
- wvenable 3y agoI'm working with an API right now that is absolutely based on duplicated code. They have a system for querying items and the API has 3 different ways depending on the endpoint. I just found a new one the other day and I hated it -- why is this one API unnecessarily different from all the rest! I'm building a library to call this API and I've abstracted over all these differences so my callers never have to know how messed up the underlying API is -- they get a consistent experience regardless.