Hacker News new | ask | show | jobs
by darioush 454 days ago
Kind of disagree with this article, when you add a "noun" (aka type), you're often introducing a new abstraction.

Abstractions have a maintenance cost associated with it ie, another developer or possibly yourself must be able to recreate the "algebra" associated with that type (your thought process) at the time of making modifications. This creates some problems:

1. Since there's no requirement to create a cohesive algebra (API), there was probably never a cohesive abstraction to begin with.

2. Requirements may have changed since the inception of the abstraction, further breaking its cohesion.

3. Since we largely practice "PR (aka change) driven development", after a few substantial repetitions of step 2, now the abstraction has morphed into something that's actually very tied into the callsites (verbs), and is essentially now tech debt (more like a bespoke rube goldberg machine than a well-designed re-usable software component).

You can introduce types if you follow the open/closed principle which means you don't change abstractions after their creation (instead create new ones and then delete old ones when they have no callsites).

2 comments

> Kind of disagree with this article, when you add a "noun" (aka type), you're often introducing a new abstraction.

The article is talking about simple "bundle of values" types; the example is the CreateSubscriptionRequest. This is not an abstraction. It is simply a declaration of all the fields that must be provided if you want to create a subscription. And it is usually superior to passing those N fields around individually.

yeah this is correct, somehow I jumped to a different conclusion :)
Not creating abstractions has a cost too. Let say you have a string which is a user_id, just define a user_id type. That'll document the code, helps avoid mistake thanks to type checking, reduce cognitive load, ease refactoring and so on.

And if you need to change abstraction at some point, then refactor.

this isn't what I would call an abstraction, that's creating a named type. named types are simple because their algebra is also simple and their maintenance cost is low.

problem is more when you have types that "do things" and "have responsibilities" (usually to "do things with other types they hold pointers to, but do not totally own"), such a type is very difficult to maintain because there's now:

- a boundary of its responsibilities that is subjective,

- responsibility of building collaborators and initializing the type

- dealing with test doubles for the collaborators.