Additive and subtractive

I wrote a while back about the idea of a 3d unprinter, and mused on the benefits of comparing and combining additive and subtractive processes. These two forms are the classic opposites of manufacturing; additive processes start with nothing and build up until it works, while subtractive processes start with an existing block of material and cut it down.

This same distinction can be a useful way of thinking about software design. We often speak about libraries and frameworks, which are both vehicles for making reusable code and sharing it with others. These terms are nebulously defined and to some extent a matter of opinion, but to me the difference is additive vs subtractive.

A library is a set of functions you can incorporate a-la-carte. A math library might include a fast exponentiation function, but that doesn't obligate you to use the square root or trigonometric functions. By contrast, a framework gives you a fully formed set of abstractions suited to a particular domain. Ruby on Rails, for example, provides you with an amazing pre-baked set of ideas distilled from the authors' experience in website development. If your problem is like their problems, you can save a lot of time and effort by going with these prefabricated designs, to the point where many websites can be generated to a first approximation with just Rails' setup and scaffolding commands and no code at all.

If you want to do something new with a library, everything's additive; you just write some more code and that's it. With a framework, the abstractions that are built are meant to cover the idea space completely. It doesn't usually make sense to just add code. Instead, you have to find a place for that code. The existing abstractions could be modified in some way, or even replaced. Regardless, the process is subtractive; you start with the general answer and cut it down to fit your particular case.

That's not to say subtractive is bad, or additive is always good. The thing is that additive is complex in proportion to the complexity of your project. If your goal is to make a new operating system, doing it from scratch is going to take longer than you likely have to spend. Subtractive, on the other hand, is complex in proportion to the difference between your project and the ideal abstract project the framework was designed for. Using Rails to make a webpage is so easy it's basically cheating. Using Rails to make a realtime message queue is harder than just not using Rails at all.

The mistake a lot of people make is not thinking about that abstract project. Both framework designers in having an unreasonably wide or vague idea ("don't worry, we made a framework for everything"), and framework users in not considering whether that abstract project actually matches up with their real one. Too often frameworks are chosen because of their popularity or familiarity rather than how well they fit the goals of the project.

Either way can be wrong, but I think subtractive has the most potential for harm. With additive programming you can at least get an idea for how far away you are. Bad subtractive programming is full of subtle pitfalls and dead ends caused by the impedance mismatch between what you want and what the framework designer assumed you wanted. In the worst case you basically have to tear the whole system down and build it back up again.

At that point it should become obvious that additive would have been easier, but that's an expensive misstep and one that's easily avoided if you know what to look for.