The Macbook roars to life with the sound of a chorus of angels. At least, that’s how I think about the bootstrap process that initializes the power of the bootROM, does POST, and then does the EFI boot chime — which is the chorus in question here. Of course, it still then has to launch the kernel, the encryption module, then the login module, then the user environment. The whole process takes 10 seconds on a slow day, and then the computer is ready to think.

Humans on the other hand don’t use processes to prepare our thinking. We use things like school to help us learn to think. We study under teachers to learn the discipline of something. And just as we use physical tools, we construct mental tools to help us think.

As a programmer, I do a ton of thinking. Over the years I’ve learned to use a few mental tools to help me think about programming — these aren’t things generally taught in school. Even though I usually use these tools in the context of programming, these tools should be applicable elsewhere too.

Whiteboarding

Whiteboarding is the ability to view and theorize problems in an abstract space and share these ideas with others. It’s a way of encapsulating a problem and a potentially heated discussion about that problem, to an abstract thinking space. Whiteboarding is to collaborative problem solving as Docker is to deploying software.

To whiteboard something, try to imagine that you are writing all the things you’re saying on a whiteboard and explaining it to another person. This doesn’t just have to be words either: you can include graphs, abstractions, drawings, jokes, whatever — it’s your abstract thinking space, do whatever helps you think! Since you’ll be whiteboarding another person(s), you should start the whiteboard by simply saying, “This sounds like an interesting problem. Let’s whiteboard this idea,” or equivalent, depending on the context of your conversation:

You’ll note that even if you use Linus Torvalds style “fuck-it-let’s-get-to-the-fucking-point-language” (which I’ve used in the examples below to help demonstrate the effectiveness of whiteboarding), whiteboarding doesn’t make it personal and lets you think more about the problem at hand. (If you are making it personal on purpose, as Torvalds does, then consider the olive branch vs hammer discussion further below).

Impromptu Code Review

Without whiteboarding: “Your code is bad and you should feel bad. Don’t ever use a string for what should be a boolean…”

With whiteboarding: “That code looks like it might be a problem, let’s go over it together and whiteboard. — This string right here will cause the code to fail. It’s better to use a boolean here, don’t you think? No? Let’s write a test and watch it fail.”

Object Design Pattern Discussion

Without whiteboarding: “Look all you need here is a facade, your subsystem is so fucking complicated I don’t even know where it begins and ends.”

With whiteboarding: “Wait wait wait, let’s whiteboard this design real quick. Isn’t this subsystem a little fucking complicated? Why not use a facade?”

During Stand Up

Without whiteboarding: “So yesterday I implemented the REST API for authorizing factory users, so that’s done. By the way, I think your build has a problem though John, because the CI failed for some fucking mysterious reason I can’t figure out.” (Ensue argument that takes 10 minutes and wastes everyone’s time.)

With whiteboarding: “So yesterday I implemented the REST API for authorizing factory users, so that’s done. Oh yeah, there’s some fucking problem with the CI: John, can we whiteboard about that right after standup? Ok.”

Whiteboarding helps separate a person’s emotions and personal attachments to a problem. It helps developers talk each other in a more abstract, rational, and logical manner. This skill is often reflected in the mantra, “You are not your code.” I think this is a critical skill for communicating effectively with other developers. Unfortunately, it’s not a skill many have — I find that having this skill is (one of a few) marks of a damn good programmer.

Whiteboarding is especially an effective skill when doing code reviews because developers hold strong opinions about the code they write. When trying to solve problems, humans naturally have a tendency to address each other — after all, the code isn’t a sentient being, so why would you talk to the code? Isn’t it only natural to direct your talking to a person, and not an inanimate object? However, by talking to another person about *their* code, you run into a number of problems:

You run the risk of offending someone when critiquing their code. This isn’t lightly offending someone either — you’re tearing down the work of a creative, professional, highly rational person and asserting that your own ideas are better. Offending someone like this destroys their trust in you and your ideas, and makes working together ineffective.

You are setting the stage for the discussion to be confrontational. Maybe you and the developer you’re working with are *both* right? What happens if you’re both wrong? If the setting for your conversation is confrontational, it makes it difficult to come to these conclusions.

right? What happens if you’re both wrong? If the setting for your conversation is confrontational, it makes it difficult to come to these conclusions. Approaching the conversation this way rarely leads to ideas with which you can experiment. Instead, it’s much stronger to drive discussions about code into a space where someone can write a proof of concept to validate an idea instead of relying on hyperbole.

Many non-technical people will think you are a complete asshole, and they won’t want to work with you in the future. Non-technical people won’t understand that even giving them a critique is a significant investment of your time in improving their work.

All of this can be avoided by pushing your discussion into a separate whiteboard just for discussing that problem. And hey, if you happened to actually be completely and totally wrong (that never happens, right?) throwing the whiteboard away is easy.

Whiteboarding encourages other people to evaluate and contribute back to what you’re saying in a more constructive manner. By thinking this way, it is easier to experiment and play with ideas and collaborate with others.

But how do you learn whiteboarding? It’s not a technique taught in schools or university (though it really should be). If you’re lucky, you’ll have a good mentor that can explain these ideas to you. Or, you can learn it the same way that I learned it: by starting with a smaller, easier technique.

Rubber Ducking

Rubber Ducking is a technique in which a programmer tries to solve a problem in the code by explaining it, line by line. Many programmers will find that simply explaining a problem to someone, even to a non-technical person, will often lead you to the solution. Involving a person, however, takes up that person’s time, so it’s better to find some sort of inanimate object to talk at to discuss the problem with yourself.

Rubber ducking is notable because it’s a form of “self-whiteboarding”, and it’s often the first kind of whiteboarding that a programmer will discover. If a programmer is good at rubber ducking — that is, creating an abstract space with which the problem can be explained and experimented on — then it’s a short step to extend this technique to accomplish whiteboarding.

Both rubber ducking and whiteboarding are skills that are built like muscles. The more your practice, rest, heal, and do it again, the stronger you’ll become.

Touch Typing

Many people think that touch typing is simply a faster way of typing. Since programming is a task where typing code is (maybe) 10% of the work, wouldn’t this make touch typing a largely useless skill? Where is the value in touch typing? This is a big myth — touch typing has little to do with “typing faster” — it’s a mental skill! Touch typing is valuable because it increases the speed at which you can interact with a computer. The faster you can touch type, the faster you can translate the thoughts in your head into usable commands for the computer. People who can effectively touch type can accurately translate their thoughts to a computer roughly 2 to 5 times faster than those who can’t. This lets you increase the flow between your thoughts, useful experimentation and play, and your computer. Touch typing, then, is the grease between the cogs of your brain and your computer.

Touch typing isn’t about how many accurate words per minute (WPM) you can type, although this is how it’s commonly measured, or even looked at on job applications. Measuring WPM is a crude, inaccurate way of looking at touch typing, and lends to the misconception that touch typing is primarily about “typing faster” — it’s not. It’s about thinking faster, with your computer.

In fact, I don’t think people who can touch type write more code than those who can’t. I do believe, however, that they spend far more time thinking about the code they write, and as a result, their code is higher quality. Why might this be the case? Well, I think that when people can’t touch type that it takes more effort to translate their thoughts into usable commands for a computer — this results in more frustrations when something doesn’t work. It results in a disconnect between the programmer’s mental model of the computer, and the actual computer. And since humans have a limited capacity for frustrations, stress, and so on, not touch typing limits a human’s ability to think when interacting with computers.

If you’re a touch typist, just saying, “I can touch type” isn’t the end of the discussion either. There are many kinds of touch typing:

“I’m copying a source document and not looking at the cursor while touch typing.”

“I’m talking to you and you’re rudely interrupting me by parading around my desk but I’m going to keep touch typing so I can end my train of thought on a productive note before engaging in a conversation with you.”

“I have this editor full screened and I’m going full speed, fully in the zone, headphones on, staring at the cursor touch typing real damn fast because I figured out the solution and need to dump it out of my brain as fast as possible before my ideas get fuzzy again.”

“I’m doing a demo and talking out loud while touch typing longer terminal commands and showing a group of people the results.”

Touch typing will lead you down the road of seeking better tools to type — namely better keyboards. Anyone who can touch type has strong opinions about the keyboard they prefer, why they prefer it, and will likely have the ability to talk your ear off about Cherry MX Blue switches vs Cherry MX Black switches and so on. If you don’t know how to touch type, you won’t be able to really appreciate the thrill that a high performance keyboard can give you.

That’s not the end either: Touch typing will lead you down the road of better ergonomics, exercises for your hands, wrists, and arms, environment optimization and so on. A good programmer (and a good touch typist) will value their tools highly. (If this sort of thing floats your boat, check out my posts on my personal battlestation.)

By contrast, touch typing isn’t going to be a valuable skill forever. I fully expect that some sort of cyberwear brain augmentation in the future will allow us to interact with computers on the scale of orders of magnitude faster. Whenever that technology happens, then it will be an important skill to “think like a computer” so you can interact with a computer in the fastest way possible. And just like having a great keyboard is important to effective touch typing, having a great cyberwear brain augmentation will be important to effective thinking. I wish I live to the day where I get to see two programmers arguing over Cherry MX Red vs Cherry MX Black brain augmentations!

Olive Branch vs Hammer

Any programmer will write components that will interact with other components that another programmer wrote. Inevitably, this leads to discussion about how shitty the other programmer’s component is, how it’s not tested well, or documented, and how if only they were using the latest X that it would solve all of their problems.

Engaging in a discussion like the above is actually fine. It could be the case that the other programmer’s component *is* complete shit, completely undocumented, untested, and that, yes, they’re using a framework 10 years too old. If that’s the case, then great, you’ve identified the problem. But what if the person you’re talking to is a junior programmer who isn’t even out of high school yet? What are you going to tell that person?

This is where you have to make a choice: Do you use an olive branch or do you use a hammer? Do you educate, or do you punish? Knowing when to use which tool is a difficult skill to acquire.

When I discover some dastardly piece of junk code that *is* going to cause production to fail, topple over, and then collapse the entire stack under its weight, and it is someone else’s code, then it’s time to figure out how to address the problem. I take several things into account when I’m trying to pick olive branch or hammer:

- Who caused the problem? Is it a programmer? A non-technical person?

- Was I able to discover the solution within the first five results of a generic google search?

- Is this the first time this has happened with this team? With this person?

- Did the automated testing catch it? Are those tests commented out? Did static analysis catch it? Did someone turn off the rule which caught that problem in the static analysis?

- What’s the severity of the issue?

Figuring out which one to use is a judgment call. There really isn’t a right answer here.

Those are some of the mental tools that I use on a daily basis. Now we wait for someone to invent a cyberwear interface so I don’t have to touch type anymore.