We default to addition
11 points by BinaryIgor
11 points by BinaryIgor
One reason might be the complaints from users when a feature gets changed or removed.
True; but sometimes (often) removing features makes overall software better :) Simplicity is beautiful after all!
Better for whom, though? Not for the most competent and devoted users (who know how to get utility out of the feature), not for checklist-drivent deployment decisions, often not for developers because they are also qualified users of the software and if the feature is low-maintenance (which should always be the goal!)…
So how do you keep both camps satisfied?
I think the answer is to make your product a platform, and provide a good API. If you're making a game, design it for modding from the outset.
See e.g. Emacs. It's used for every damn thing on the planet, from games to PIM to email to IRC to Usenet, and yet it's still (by modern standards - see Eight Megabytes And Constantly Swapping!) fast and lean. The reason is that all those extra features are built by the community as optionally installed packages. There's no reason you couldn't take a similar approach with a commercial product.
The goal is not to satisfy the minimalists, the goal is to make sure their criticisms are irrelevant to the groups you need to satisfy. So memory consumption by unused features should probably be minimised, it's indeed a good idea not to do all the initialisation without need, let things stay not-paged-in. Of course the feature in question should not dictate any cross-cutting property of the program.
I suspect that the most useful kinds of platform positioning don't always work too well with some kinds of lock-in management, and thus are crippled when they happen in commercial products…
While I appreciate the sentiment and concerns about bloat, I've found that organisations that don't default to addition usually default to subtracting people:
I like this idea on principle, but was hoping for some good worked examples of subtractive problem solving. I can make up my own, but I'm interested in what other folks come up with.
Something like:
One time I proposed removing AWS SNS from a system as it was extending the API surface in counterproductive ways and promoting spaghetti interaction between microservices, while adding no real value. I think that would qualify as subtractive. I got a lot of pushback along the lines of "it's already there, why make the effort to remove it" and "surely it was implemented for a reason" 🤷
I think subtractive solutions mean both refactoring and revising architecture with the goal of having fewer, more powerful and less leaky abstractions, and reducing the number of moving pieces in the system, as it were.
In one system I worked on, I needed to extend our users model with some additional capabilities. We had two services that must have been changed: user-service & auth-service.
I ponder possible implementations given current status of the system and it seemed overly complicated. Then I thought - should these services be separate? They do similar things and are interdependent in many ways; wouldn't this feature and system in general benefit from the merge?
And yes, I turned out to be soo true; I merged auth-service into user-service as its another module. In the end, I've implemented said extension only in the user-service and removed something like 2 to 3 thousands LoC + full-blown service while adding new functionality :)
The river crossing problem is an example of a similar cognitive bias. For those who haven't seen it (I presume most have), you have to get three things across a river in a boat that can carry one thing. The problem is that you have three things (e.g. wolf, goat, grain) where two are food for the other two (e.g. wolf eats goat, goat eats grain) and you can't leave one of the things that eats one of others unattended with the thing it eats.
To a computer, this is a trivial problem. A depth-first search of the search space gives an answer quickly. The first step is easy: you must take the goat, any other option is invalid. The second step is obvious: taking the goat back reverts to the initial state, so can't be correct because any sequence of steps that involves a return to a previously explored state is wrong. And then you have two choices, so try taking the wolf. Now you have the wolf and the goat on the other side. A computer will see moving the goat back as the only available choice (taking the wolf back is the equivalent to reverting to the previous state, so not a valid option).
But, to a human, taking the goat back appears to be backtracking: your goal is to move things from the left side of the river to the right, moving something from the right side to the left is moving the wrong way!
A lot of people get stuck at this point. The backtracking move is just something that they are cognitively blocked on.
I think the additive vs subtractive discussion here may be a special case of this general cognitive bias against backtracking.