Subtasks vs Capabilities

There exists a myth about software: that we can start with what we want it to do, break that into subtasks and subtasks of subtasks that we can each specify completely, implement all those subtasks, and then assemble them into something useful.

Harold Abelson explains it in this classic lecture (h/t @pesterhazy for the link). He also explains the problem, and a solution.

He draws the hierarchy of subtasks. If we learn something and need to make a change at a spot in the middle, the work below it is all invalidated. And changes to that specification may ripple out to the sides, ruining everything.

Look at all these elegant subtasks, suddenly rendered worthless

That hierarchy of subtasks seems rational, but it is not practical. Instead, Abelson points out, the way things really get done is in levels of capabilities: fleshed-out subdomains of the problem. If we want to build graphics, then we need a capability of making shapes, and for that we need a capability of locating points. Each of these has its own vocabulary and implementation. Each is coherent and broadly useful, specialized to a problem domain but not a single task.

Abelson is working in a Lisp, and Lisp makes it easy to write mini-languages to solve each problem. So his capabilities work out to levels of language. Build a language to describe points and locations, then geometry on top of that, then combinations on top of that.

When something changes, chances are you can express the new need at one of the higher levels without changing anything further down.

The capabilities (his “language levels”) use each other flexibly.

These are capabilities. We need the capability to describe points, then a capability to assemble them into geometries, and on that we can build a capability of combining those into useful images.

The capabilities depend on each other, and they have specifications, but each is broadly useful. They are built for a range of closely related purposes, not one specific place in the whole.

This myth also exists in our companies and societies.

A culture is like a big organization which assigns each of its members a place where he can work in the spirit if the whole…. In an age without culture… forces become fragmented and the power of an individual man is used up in overcoming opposing forces and frictional resistances.

Wittgenstein, Culture and Value

Here, Wittgenstein is very wrong. (To be fair, he didn’t publish this; the book is a posthumous collection of notes.) A culture certainly doesn’t break work into subtasks. But our companies do!

And it doesn’t work, either. You get rigidity, you get people held back by needing to go through others for specific subtasks. When infrastructure, purchasing, and marketing are elsewhere and we are required to delegate to them, this creates friction. The subtasks are never independent, so this doesn’t work even in theory.

Instead, create capabilities. For instance, to make useful software, we need infrastructure. Don’t create a subtask, assign it to a team, and make every software development team wait on them. Instead, create infrastructure as a service. Form a capability, not a fiefdom.

Build teams and software as capabilities, not subtasks.