In episode 41, I list five principles for reducing the cognitive load of Doing the Right Thing in a workplace. They involve shifting work onto the environment or the body. The rough idea is you get pushed into doing the right thing rather than having to decide to do it.
The principles are:
- Favor direct control links from perception to action.
- Prefer composite values over atomic values. Avoid primitive obsession.
- Discover or create affordances.
- Maintain invariants and rhythm.
- In addition to actions that achieve goals, also design actions that seek new affordances.
In episode 42, I plan to describe work-related examples.
After the break, I give a very, very, very rough draft of some examples that have come to my mind. I’d prefer to also harvest examples from other people, perhaps in a group zoom-like call so I can record people. If you think you have some, please contact me at firstname.lastname@example.org.
My premise is that these same principles can be applied to structure behavior seemingly very different from throwing or diving.
A simple example is the early 2000s trend of putting displays of status (such as whether the current build succeeded) in people’s peripheral vision, arranging for them to change noticeably (quite often by changing color) if something bad happened. Like a movement you catch out of the corner of your eye, they afforded turning to look at a potential danger. Fairly trivial, but letting perception drive action worked better than relying on people to actively check status.
Test-driven design is my favorite example. Toward the end of the last century, I was a proponent of writing tests first, but *all* the tests first. I thought the classic “write a test, see it fail, make it pass, do some cleanup” loop was equivalent. I was wrong, as I learned when I actually tried TDD instead of reasoning about it.
TDD is much better for creatures like us, because it has a cyclic rhythm like that of walking. My style did not, so was inferior.
Or consider creating a branch of the code base, coding on it a while, submitting a pull request, and then merging. You can argue, I suppose, that’s a cyclic process, since you do it again after you’re done. (Sort of, though waiting for PR approval overlaps the beginning of the next cycle.) But it has problems:
1. The cycle is way too long. We’re much more attuned to fast cycles than slow ones.
2. It lacks direct control links. In TDD, a failing test immediately affords the next action: making it pass. That is, in a sense, seeking the next affordance: a passing test, which shuttles you off to the next action. In branch-based development, there’s not a clear prompt for when you decide to make a pull request. PR approval is a prompt to merge, but it arrives asynchronously, which is destructive to rhythm.
Carpentry is easier when you cut with the grain of the wood than against it. Another way classic TDD cuts with the grain of human perception was its famous “red-green-refactor” loop, where code that failed a new test provoked a substantial red bar to appear. When the code successfully passed the test, it turned green.
Most humans are sensitive to changes in color; it registers as a sort of movement; that makes “red bar / green bar” a stronger affordance.
Because I used to do everything within emacs, including running tests within a shell buffer, I tended to use non-colorizing test runners, reasoning they were just as good. The ones I used printed a period for each passing test and a capital F for a failing test. That’s OK: the periods are fairly unobtrusive, a sort of background noise, so the sudden appearance of an F was movement-like enough to catch the attention. But I now think colors are better.
I have on occasion used test runners that – at least by default – print a whole (uncolorized) line for both passing and failing, with almost no visual distinction between them. It was frustrating, both in practice and in the principle of the thing: they were deliberately throwing away prior art, reinventing the wheel, except making it square.
≤ short music ≥
One of my favorite examples is the metaphor of “code smells”. The phrase comes from “Grandma Beck’s Rule for Child Rearing: If It Smells, Change It”, but I wonder if it co-opts a direct control link: the impulse to draw back when you smell something awful. That’s reaction is weaker than the reflex to pull your hand away from a hot stove, but it’s still there.
Code doesn’t really smell, but people who use the metaphor do seem a lot like my wife putting cows into the diagnostic categories “bright” or “dull”. (See episode XXX.) That is, they perceive wrongness in the code first, then justify the perception with reasons later, if pressed.
Is it possible that there’s some neuronal pathway predisposed to react to perceptions of danger that can be trained on new sources? Something like the way babies have a general predisposition to learn about faces?
Harnessing a control link that says “React!” is a good idea when we know from experience that if you let the typical pressed-for-time programmer *decide* whether to improve some code, the job will too often be left undone. So make it harder to ignore bad code.
Now, is this gestalt-ish perception of bad code an *actual* direct control link, or is it just something *resembles* one? I don’t know, and I’m resolute that it doesn’t matter. As I try to belabor, the “applications” section of an episode are looking not at whether the theory presented is true, but if it’s *useful*: has (or may get) a track record at sparking ideas or insights that can be tried out.
With that dodge out of the way, I think it’s interesting that the act of refactoring can be seen as a search for new affordances. Here’s a quote from Ron Jeffries I use a lot:
“Beck has those rules for properly-factored code: 1) runs all the tests, 2) contains no duplication, 3) expresses every idea you want to express, 4) minimal number of classes and methods. When you work with these rules, you pay attention only to micro-design matters.
“When I used to watch Beck do this, I was sure he was really doing macro design ‘in his head’ and just not talking about it, because you can see the design taking shape, but he never seems to be doing anything directed to the design. So I started trying it. What I experience is that I am never doing anything directed to macro design or architecture: just making small changes, removing duplication, improving the expressiveness of little patches of code. Yet the overall design of the system improves. I swear I'm not doing it.”
Keep fiddling with the code in certain ways that have a track record of improvement until you perceive an affordance of comfort, something like the way a rabbit who’s no longer hungry will look for a safe place to rest.
Here’s an example that might seem even more dubious. As I’ve mentioned before, my wife and I used to dance tango, specifically close-embrace tango, where there’s no space between the partners’ chests. For an example, see the episode’s custom image. That’s my wife, Dawn, embracing a man who is not me.
“Entering the embrace” is a little ritual that involves the arms, but – more importantly – is about inhaling, raising the chest up and out, and leaning forward for contact. To me, it changes my state from the normal one of intense self-absorption to one where I’m attentive to the movements and reactions – the body language – of my partner.
I’m not good at remote pair programming. Part of the reason is that I’m a bit face-blind; I’m not good at detecting subtleties like reluctance. That’s bad enough when the face is full-sized; it’s much worse when it’s tiny.
At pairing and in-person meetings, I attend considerably more to posture and stance – to body language. You could those are the affordances that affect me.
One time when I was to start an in-person pairing session, I decide to begin by doing a sitting-down version of entering the embrace. (Chest up, lean forward, no arm movement – I’m not a *weirdo*.) It seems to help, so it’s a habit of mine now. It’s not a direct control link – it’s more like one of those contextual neurons that help determine how a cockroach scatters.
The first problem with that is, as I was drafting this episode, I immediately thought of the now-mostly-abandoned idea of “power poses”. The idea is that if you assume a physical position associated with power, like standing with your hands on your hips, elbows out, that will quote “produce power” in the short term (like during that salary negotiation). Kinda sounds like the same thing as my tango pose.
I protest that, as far as I know, power poses were assumed to be innate, whereas the connotations of my tango pose were *learned*. I created an affordance that I repurposed.
A more serious objection – expressed I think by one of Barrett, Clark, or Chemero, I can’t find which – is that this is dumbing down the influence of the body to something like the banal “it’s harder to think when you’re really hungry”. It makes the body a crude modifier of the *important* stuff located in the brain. To EEs, the body, the body’s environment, and the body’s brain form a coupled system that evolves over time. Ibt’s hard to tell a story of my tango pose that looks like that. There’s no action in the environment, there’s no change to the body, there’s no dependency on time or timing – so much of what EEs want to see is missing.
I could say “Eh, OK, but what matters to me is that it helps” – and to some extent I *am* saying that – but my real reason for adding the anecdote is that my tango pose *is* pretty mundane. It’s a simple, one-way, single-time cause that hardly justifies all the background I covered. The truly ambitious EE would look for something cyclical and self-sustaining, like test-driven design. I encourage you to be that person.