To move fast, move slow

There are some incrediblly fast programmers who can complete a large rewrite of a medium-sized codebase and drop a thousand-line diff in five or six hours. A quick

git add .
git commit -m "backend refactor"
git push

later and the entire codebase has been upended. It’s impressive, really, and I say this without a hint of irony. To immediately start executing massive changes without faffing around for weeks is genuinely a skill worth emulating.

Unfortunately, that is the only part worth emulating. Because when you drop that many changes all in one commit, any semblance of thought that went into them is completely lost to time. And it really was just a semblance of thought to begin with, because there is just no way to write code that fast while thinking deeply about what you are doing. There are no explanations, only bugs and bad UX choices.

The consequences are obvious. You wake up the next morning, everything is broken, and it takes the next few days just to fix things up. And if there are a few parts that you want to revert later for whatever reason, you have to trudge back through the codebase, figure out what does what, and manually undo the changes one by one. After all, git revert will do you no good if you are only nominally using Git in the first place.

I can’t help but think: if only you took the time to properly think your changes through and make good commits, we wouldn’t be in this mess in the first place.

The pitfall

But this is not just an essay about Git. Rather, it is about a common pitfall that people fall in: trying to do things quick rather than doing them right.

Picture this. You’re taking a calculus class, you don’t understand differentiation, and there’s a test on it tomorrow. So instead of sitting down for a week, asking yourself “what is differentiation really?” and shoring up your understanding, you memorize the derivative of xnx^n and sinx\sin x. And that is enough to pass, so you rinse and repeat.

If I lay it out like this, the problem becomes obvious. If you never take the time to understand even the most basic of concepts in calculus, of course it seems impossible no matter how much effort you put in. Yet what a pernicuous trap it is.

You need to put in some effort to do anything meaningful. That is just a fact. But we extrapolate too far. In our heads, hard work looks like staring at a textbook for six hours a day and grinding derivative exercises, rather than sitting on a couch and vaguely wondering “it’s a little weird that I don’t actually know how we get from rational numbers to real numbers”. It looks like writing thousands of lines of code in one night rather than taking a walk and asking why access control in every Git host sucks so much. But working hard and actually getting something done are not the same.

Of course you need to do exercises in order to understand calculus. And yes, I know that all my brilliant ideas for a Git hosting service won’t do me any good until it exists. But you also need to ask the fundamental questions: what is really going on here? How can I make these complicated ideas as simple as possible? And how would I explain it to another person?

Category theory

The right thing to do when you don’t understand something is to take a step back and ask: “What underlying idea am I actually missing? Why don’t I understand this?” This much is obvious. Yet knowing this does not make you immune to falling in the pitfall. At the very least, it didn’t save me.

A few months ago, my algebra professor gave a very fast presentation of category theory. If you understand the universal mapping property of the free group, you can easily guess how it went. First we discussed categories, then functors, then natural transformations, and finally adjunctions. As a homework exercise, we were asked to prove that some pair of functors were adjoint, and I knew it was a really trivial verification.

Yet I could not for the life of me understand what an adjunction was. So I look at the Hom-set definition and I am immediately greeted by more confusion. What is a Hom-set? And how on earth do you get a natural transformation between two Hom-sets, I thought you needed a functor for that? And what is a natural transformation, actually?

So I kept spinning in circles. I stared at the definition of an adjunction, digged through the terms that I didn’t understand, realized I still had no clue what an adjunction is, and went back to staring at its definition. A few days later I push some symbols with the counit-unit definition and hack together a solution. In the process I gained very little understanding of what was happening.

Now fast forward to a few weeks ago, when I decide to bite the bullet and write a category theory section for my algebra primer. Now I have to step back and think: what is a category, really, and how do I explain it? How do I build up to a functor? A natural transformation? And an adjunction?

A week later and the concept of an adjunction is crystal clear to me.

In the process I realize that many of the things I wrote were pointed out by my professor in class. So really, if I had taken fifteen minutes to think “why did he talk so long about reversing this arrow, and how do I use that fact to update my mental framework of category theory”, I would have understood the hom-bifunctor (and by extension adjunctions) half a year earlier.

Burnout

I have a confession to make. Officially I should be re-implementing email-password authentication for work. But I’ll be honest with you, this is probably the fourth or fifth time we are doing this, and I’ve gotten really sick of it. (In fact, this is the reason I thought to write this essay to begin with.)

But I’m not here to complain. My point is that you and I are both smart enough to tell when we are running in circles. Re-doing something because you didn’t think it through the first time is a sure-fire recipe to burnout.1 And the worst thing about this kind of burnout is, when you feel the work you’ve done before is pointless, you’re right.

So how do you avoid this? I confess I do not have all the answers, but here is what I think. Sitting back on a couch and thinking for half the day is nice. It is relaxing. It doesn’t carry much risk of burnout. So it is tempting to conclude that you have to trade all of these comforts away to do real, hard work. I admit you have to make this sacrifice sometimes. But I am becoming increasingly convinced that most of the important work gets done in the shower, on a train, or by nature, rather than at a desk.


  1. Especially when it’s due to circumstances out of your control, but that’s a story for another time.↩︎