“The first book is just practice.” – Jerry Weinberg
Practice means low stakes, low pressure.
You don’t make promises about outcomes, to yourself or anyone else. The only expected outcome of practice is: more practice.
You can’t get an F at practice. Grades are not the point. The only grade for practice is: present.
That thing you’re working on that looks so important today could look like practice in a year. In five years. Ten. The wider the scope, the lower the stakes. The more it looks like practice.
From that point of view, not doing a thing because you don’t think you’re ready for it, because you might not do a good job, because you might not have the time to do it just right, because it might not meet your standards or someone else’s, because of what they might say or might think… These are bad excuses and terrible habits of mind. Future-you will be disappointed, present-you will be bored and anxious.
Lucky for you, you can get started instead, because it’s just practice.
People try out unit testing and give up because it’s hard.
There’s usually some code in the codebase that’s easy to test, and clearly valuable to have tests around. Stuff with few or no dependencies, with clear mappings of inputs to outputs. This stuff gets tested first and inspires few complaints.
But when we try to test the other stuff, it gets messy. The tests get long. They require a ton of setup. And when the code-under-test changes, we often find it difficult to update the tests. Sometimes a small change breaks a ton of tests. And so on.
Sometimes people run into this sort of thing and decide unit testing is hard or it’s not worthwhile or “it doesn’t work with the way I write code”.
Other times, people aren’t so hasty. They look at what’s causing a particular pain. They ask themselves, “Why is this hard?” and figure out how to change the way they designed that code so that pain goes away. The hard-to-test code starts to look more like the easy-to-test code.
That latter approach feels good, even just the first time. So they do it again. And again. It snowballs, and they get better at unit testing and better at design. (Because testability and good design are friends.)
You think you want x, but maybe what you really want is something that comes along with x. And maybe there are other ways to get it.
What’s the goal behind the goal?
This is a useful question when you feel stuck. When x feels impossible. It’s a jiggle, a nudge that shifts your perspective a little bit and might just give you an answer or a thing to try.
It’s a useful question in a negotiation or conflict situation. If you feel at odds with somebody, asking yourself about your deeper motivations (or theirs) can turn up new ideas. Maybe there are ways in which you each can win without the other losing.
It’s a useful question for productivity, too. Focusing on root causes and bigger pictures is the road to leverage. It’s how you find ways to do more with less. It’s how you find the little changes that provide big benefits.
Another driver cuts you off on the highway. Asshole!
You speed around, pull up alongside him, look over, and give him the finger.
…just as he’s looking over at you, waving and mouthing “sorry”.
I want to get better at finding the moment between thinking and reacting.
I want to learn to not react immediately to a negative stimulus. Or any stimulus. I want to give myself a moment to orient and apply wisdom. I want to drive a wedge between stimulus and reaction, for thinking.
One way to help do this is to slow down, to not think about so much all the time. Mental slack leaves room for calm, for mindfulness.
Flip that around and it feels more true: Lack of slack makes me feel like I don’t have time to think.
Let your actions follow your goal. Set a new standard for yourself that you don’t currently meet. As soon as you do this, you’re in a failure state. So fail for a while, but with a direction. Work toward not failing.
The other way around: Let your goals follow your actions. Try shit. Explore. And… what? Declare that you’re “better” when you realize you’ve met some new standard?
Does the road get paved ahead of you or behind you?
It’s a trick question. Path one can’t exist without path two, and vice versa. You need to explore to decide which goals are worth heading toward. You need goals to have a reason to explore.
There’s a list of things that you’re going to do today. Cook dinner, wash the dishes, fold the laundry, feed the cat. Get through the day. Make sure the trains run on time.
But that’s not how you’re going to spend all your time today. You’ll choose how you spend the rest. Maybe you’ll read a book. Maybe you’ll watch TV. Maybe you’ll jog. Maybe you’ll work on a side project. Maybe you’ll learn C#. Maybe you’ll get some extra sleep. Et cetera.
Your options are vast. Some are better than others. But “better” is subjective. You choose.
But, of course, I have opinions:
When you choose, look for effectiveness. What can you spend your time on that will actually affect the world in a positive way?
When you choose, look for leverage. What can you spend a little bit of time on that you’ll see large benefits from?
When you choose, look at the long term. What can you spend your time on today that will make your life better in a day, a month, a year, five years?
When you choose, look at the day-to-day, from the outside. What could you spend your time on today that would make life better every day from here on out?
Also: When you don’t overtly choose, when you don’t consciously choose, that’s still a choice. And probably one you’ll regret.
I learned to write code procedurally. “Here’s a problem; tell the computer what steps to take to solve it.” That’s cool for learning how to tell a computer what to do. It’s an invaluable mental model, and it’s worth practice and attention to keep that skill strong.
But after you master that way of thinking, you pretty quickly want to transcend it. When you start to consider the lifecycle of production code – the fact that it needs to be read and changed and maintained – you benefit from orienting your thinking around transformations.
The thing we work with isn’t code, it’s code-over-time. Your ability to make sensible transformations to your code over time is what makes you effective. Making your changes simple and coherent means you can evaluate them quickly. Refactoring? Make a small change, then review the bigger picture. Adding a feature? Add a small piece, review the whole.
You’ll start to live in the feedback loop this creates, so you’ll want it to be short. You want builds, tests, and deployments to be fast. You’ll want mistakes to show up as soon as possible. That makes their causes clear. It makes fixing them fast.
This is valuable outside of code, too: Make a small change to your routine, evaluate. Make a small change to your team, evaluate. Make a small product decision, evaluate. Make a small change to the org chart, evaluate. Et cetera.
Delaying feedback creates fragility. That happens when we give in to the temptation to make our transformations too big.
When many people are accountable for something, nobody is accountable for it. When we all say “somebody else will deal with it,” often the result is that nobody deals with it.
This is an actual, scientifically-observed psychological phenomenon. It’s called the Bystander Effect. Also observed: The larger the group of bystanders, the less likely anyone is to intervene.
We need to fight this. And the way to start is by going first, by taking on responsibility and accountability. By not being bystanders but being participants, helpers, doers.
If you’re walking by and you see the coffee pot is empty, make a fresh pot.
If the team needs a volunteer and nobody’s speaking up, speak up, volunteer.
If you see someone struggling with their code, offer to pair or to be a rubber duck.
They don’t teach the A students how to work with the B and C students. In my experience, at least, all the A students were kept together in “honors” classes. We were led through harder material faster, while the B and C students did their own thing. There’s some value in that, but it also creates problems down the road. In real life, I’ve never worked on a whole team of A students.
Sometimes maybe you’ll be the smartest person in the room. And maybe you’ll assume everyone that will recognize that, and that they’ll listen to your sage advice. They won’t. If you’re really so smart, listen: You need to understand how to work with them and how to help them. If you can’t do that, you’ll resent them. And you will move on to the next “them” and quite probably resent them too.