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 they’re broadly useful. They are built to a range of closely related purposes.

The same is true 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. To make useful software, we need infrastructure and purchasing and marketing. Create infrastructure as a service, so I can help myself. Create teams that consult on purchasing, and that provide advice on marketing. Yes, we need expertise in these, but not delegation. Delegation is blocking. Make products, all the way down.

Build teams and software as capabilities, not subtasks.

Tools -> capabilities -> acclaim

Here’s a lovely graphic from the folks at Intercom. It describes the difference between what companies sell and what people buy.

Even though customers buy this [skateboard parts]… they really want this [cool skateboard trick].

We don’t want the tool, we want what we can do with the tool. Take it further – maybe what that skateboarder really wants is: the high fives at the end.

skateboarder getting high fives from the crowd

Our accomplishments feel real when people around us appreciate them. If the skateboarder’s peers react with “Why would you do that?? You could die! You look like a dumbass,” titanium hardware doesn’t shine so bright.

It reminds me of the DevOps community. Back when coworkers said, “Why are you writing scripts for that? Do you want to put us out of a job?” automation wasn’t so cool. Now there’s a group of peers, at least online, ready to give you high fives for that. The people you meet at conferences, or get familiar with on podcasts, or collaborate on open source tools with — these take automation from laziness into accomplishment.

Giving developers polyurethane wheels and hollow trucks won’t let them do tricks. Move to a culture of “our job is to automate ourselves out of better and better jobs.” Give us the high fives (and let us pick our tools), and developers will invent new tricks.

Increasing potential as a specific output of flow

In Projects to Products, Mik Kersten divides flow items in software products in four: features, defects, risks, and debt.

If you only count features added and bugs fixed – changes visible externally – then you neglect the other outcome of our work: the next version of the team+software.

I prefer to think of “technical debt” work as groundwork for future changes. I like Kersten’s suggestion to do more of this at the beginning or a release cycle, while preparing to add a lot of features.

Pretending that software is “done” at the end of a project is dangerous. Naming risks and technical debt as part of the output of flow makes caring for our future explicit.