Let’s talk about steps and value.
Out in the world, folks make a lot of decisions involving these ideas, they reason about them. We want to make sure our reasoning is based on a thorough understanding of the implicit premises.
What’s a step? A step is a gap or space, in time and activity, in between two points, a Before point and an After point. At the Before point, a system is "ready". At the After point, a system is "ready". In between, during the step, the system is "unready".
That idea, of ready or unready, needs a little elaboration. Remember that the change-harvester’s vision applies to lots of different contexts where change is sought. And ready or unready really only have meaning in the particular context in which we’re making changes.
Today, I’m going to limit my context to seeking changes in a codebase that is already shipping. Later in the thread, we’ll wonder about different contexts, but for now, let’s just narrow our focus.
Our context and definition of "ready":
Our program is in the field. It was generated directly from the codebase at some point in time.
A change is "ready" if we would have no concerns refreshing the fielded program using (codebase+change) instead of just codebase.
Now, there are two features of this definition of ready that should jump out at you. 1) its "negative capability" aspect, 2) its "indifference to cost of deploy". These are both important to think about.
Negative capability: This definition of ready can be translated to "the change does not make the user’s life worse". A lot of folks define ready, some only implicitly, as "it does make the user’s life better". So why is this definition different?
If you’re a geek, think of it this way: we’re changing a "greater-than" to a "not-less-than". Any given ready change may or may not make the user’s life better, but if it makes the user’s life worse, it’s not ready.
Indifference to Deploy Cost: This definition of ready is decidedly not considering how cheap or expensive it is to actually deploy the change. Deploying a change to a static website is comparatively cheap. Deploying a change to a car’s firmware is comparatively expensive.
If you’re a product-expert maker, think of it this way: "ready" means, if deployment were free, it would be possible to deploy (codebase+change), regardless of whether it would be desirable.
When to actually deploy a change is based on considerations of market value balanced against considerations of deploy cost. Both of these sets of considerations are outside of this definition of "ready".
Two words we often use in this context to capture the idea of ready: "green", and "shippable". Like most shorthands, if you’re not familiar with the underlying formality, these can confuse folks. That’s why we spent so much time on defining "reaady".
So a step is a gap between two points of ready. That gap represents a period of elapsed time and a chunk of actual effort distributed across it, during which a change is unready.
Now let me throw you a bomb:
Ask a change-harvester:
"how can I get more value more quickly?".
Her most common answer by far:
"Take many more significantly smaller steps than you are taking now."
Does that seem counter-intuitive? It would surprise me if it didn’t. Whatever your specialty is within your team, product, database, backend, frontend, odds are good that your entire professional life has been saturated with the idea that "bigger steps make value more quickly".
You’ll have received (&likely contributed) an enormous amount of theory, analogy, reasoning, arguments, and words supporting "bigger steps make value more quickly".
Sadly. It is not true, not only in your specialty, but in most domains where it’s taken for granted.
This is a classic idol of the schema, by the way. See the article here for my explanation of that phrase: Idols of the Schema: Ignoring Data While Overvaluing Ideas
Nearly all of those analyses are based on two mistaken ideas: 1) That steps contain no inherent value, and 2) That the effort of a step is linearly proportional to its duration.
Second one first, then, that the cost of a step is linearly proportional to its duration. If it takes me 1 unit of enery to take a step of duration 1, it takes me 2 units of energy to take a step of duration 2.
Because of the domain, a step’s cost involves not just the number of textual changes in the code, but also the requisite "mental manipulation" that drives those changes. Trivially, the bigger the change, the bigger the number of things the mind holds while making it.
But all of the mental manipulators in question are humans with brains residing in bodies. And the line relating "things the mind holds" to performance is not remotely linear. It is shaped like the outline of a knee, it holds the line for a short period, then dives downward.
How long is that linear part? Far shorter than most of us take for granted. For very familiar closely related concepts, think of the low two digits. For unfamiliar and unrelated concepts, think of the low one digit.
The limits on human mental bandwidth are stark & severe.
Now what about this other idea, that steps carry no inherent value, have no particular merit simply because they are steps. Again, we turn to the specific domain, and within that domain the humans, to break that timber pillar into the kindling it really is.
Every single step ends at a "ready" point, by definition. A ready point has these inherent values: 1) closure, 2) interruptability and 3) woot-juice.
Closure is a human value. Remember our bandwidth issues from before? When we get closure on a step by hitting ready, we can put the details of that step in a box and close that box. They are no longer relevant, because we’re ready.
Interruptability is a human value. When we’re between ready’s, we can’t do anything but get to the next ready. We can’t answer questions, feed the kid, take phone calls. Most importantly, we can’t change direction, either. We can’t respond to the (human) market. We can’t steer.
Woot-juice is a human value. Getting to ready is a win, and going "woot!" makes our bodies reward us. We call this "rhythm": alternating periods of tension and release. Humans respond to rhythm with renewed energy and renewed joy.
I’m running long, here, but quick like a bunny, lemme tell you a story.
Over the last four days, I’ve been advising gee-kid on an important transformation to his codebase. (For the geeks, we used null object and the strategy pattern to kill hundreds of lines of risky dup code.)
We took about ten steps. (I say "we", but all I did was rubber-duck and throw a little advice about step-ordering. He did all the heavy lifting.)
Non-linearity of human bandwidth: Each step took 90 minutes max, 15 minutes min, and involved a single adjustment to a single aspect of the program. This kept him able to think clearly, and me able to get what the hell he was talking about.
Closure: After every step we ran our "tests", it’s not a TDD’d codebase, so that meant whole-app runs and comparisons. Since they kept demonstrating ready, we were able to forget the preceding change. We opened and closed the box 10 times.
Interruptability: Four days elapsed but only about 10 hours of geek-at-keyboard happened. We both did lots of other things, like meetings, emails, feeding and walking the dogs, writing muses, and so on. We were free to do that because we were interruptable.
Woot-Juice: We had a great time. We celebrated each win, sometimes to our surprise, and we fed like vampires off the energy those wins gave us. We never got bogged down, lost focus, or stormed away in a fit of pique. We were at frequent intervals, you’ll laugh, high on geek life.
At the end? He was amazed at how quickly and cleanly and confidently we got to our value, just by taking many more much smaller steps.
So, look. I am not asking you to believe my theory. I am asking you to also not believe long-step theory. Don’t buy the theory, try the practice.
Take many more much smaller steps on your next change, and see how it goes.
And get back to me.
The GeePaw Podcast
If you love the GeePaw Podcast, show your support with a monthly donation to help keep the content flowing. Support GeePaw Here. You can also show your support by sending in voice messages to be included in the podcasts. These can be questions, comments, etc. Submit Voice Message Here.