Go slow to go fast
Monday, February 19, 2024
A couple of weeks ago, I started working with a personal trainer to improve my fitness. I've long been an endurance athlete, and it's time to lean into my overall fitness and strength. Part of this is to be healthy and live a long life. But honestly? More of it is a desire to come back stronger and beat my old personal records.
As part of the training, I'm building skills I've not worked on before and I'm confronted with being back at the beginning of something. My workouts include work on strength and flexibility, but the hardest is everything around stability.
An exercise that my trainer has me do is palm side planks. There are a few variations on this, but the position I end up in has me on my side with one foot and one hand touching the floor, my feet and hips stacked, my back straight, and both arms fully extended. One hand touches the floor, the other extends toward the ceiling. This is an exercise in strength and balance, and it is so hard for me.
At first, I tried to just swing right up into that position as quickly as I thought I should be able to. I'd go into the position, then wobble and fall. Up, wobble, fall. Up, wobble, fall.
Eventually I learned that I need to go smoothly and slowly into position, focusing on keeping the right form. I get there more stably, and I can hold it better, and over time I get up into it faster and more reliably. Some days I still fall, but less.
This holds for my other exercises, too. The instinct when your muscles hurt is to get through it as quickly as you can. This leads to bad form, and bad form leads to injuries. You have to slow down and concentrate on getting the form right, and complete the exercise slowly and smoothly. If you can't complete it smoothly at low resistance, you're not ready to go faster or with higher resistance.
This holds true for everything you want to improve. I'm a software engineer and a programmer. I like what I do, even though I found it by accident1. My love for software engineering grew over time through mastery, and I put a lot of time into practicing my craft.
One of the ways to practice software engineering is to do it, deliberately, over and over. The key is to pick something at the right level of difficulty. Too easy or too hard and you won't improve. You're not going to become an expert software engineer by writing fizzbuzz2 or fibonacci ten thousand times. And you're not going to start by making a new programming language or creating a new operating system.
What you need is something right at the edge of your abilities. Something where it is achievable, but hard. This will be uncomfortable most of the time, the same way a difficult exercise is uncomfortable, until you learn to enjoy and accept the feeling of discomfort by associating it with improvement. You have to pick projects that are just beyond what you can do today and push through that barrier until you get better at it.
When you're working on those projects, you have to introspect and examine what you're doing. Look at the approaches you take and how you solve problems and how you implement things. Examine it the way you would watch your form during a workout, and repeatedly correct yourself.
This is a very slow process. The desire is to just be an expert, to try hard things now so you can do them! But by focusing on small details and getting your form perfect for each small piece, one by one, you build up to being able to do the bigger projects well.
Part of the difficulty is knowing what is actually achievable for you and what's not. This is where a community3 and a job can help, because you'll be around people who are beyond where you are and who you are beyond, and you can all help each other. And in a work context, your manager wants you to succeed and grow4, and part of their job is matching you with a lot of work you can do very well and some work that will really stretch you. It's not out of kindness, it's so that you can be more valuable to the team. But the goals align nicely.
Here are some of the projects I've worked on throughout the years as deliberate practice to stretch my abilities. I hope these can serve as inspiration and as an example.
- From-scratch common data structures and algorithms which I'd used but didn't know how they worked. Among others, I implemented linked lists and hashmaps and sorting algorithms. This one was early in my computer science degree to understand how these work and how I could write similar things.
- A mini map-reduce framework in C++. I worked with Hadoop at my internship but didn't know how it worked, so I made a small version. The key to making this achievable was removing the distributed computing component and having it run on only one machine, using threads. Problems like this are nice for finding your limits, because you can start with a very small, very constrained version of the problem and ratchet it up until you find the hard part.
- A simple key-value store copying Redis's API. This pushed me to learn a lot about how databases and systems programs and parsers work. It was achievable because it's a small project with a lot of resources out there.
- Working through Crafting Interpreters in a different language. The book used Java and C, so I used Rust. This forced me to ensure that I understood the concepts and also pushed my Rust abilities. I had to understand why things were done that way in Java and C so that I could convert it to the slightly different Rust version.
For each of these, I had to go slow to go fast. I always wanted to jump to the end result, just move straight up into the palm side plank. But if I do that, I fall over.
Instead, I had to go slow and build my understanding of what I was doing. What is the design of a key-value store? How should I write mine? How does a hashmap work, and how do I implement one? Why is the interpreter using this particular design? Do I need it, or can I do something different?
Then with each question answered, I could move through the code. Slowly, deliberately, answering questions. When I would speed up and take shortcuts, it would bite me and I would make mistakes that I found later on and had to do major rework for. When I went slowly and deliberately and gained a deeper understanding, these were fewer and further between.
There are lots of ways to deliberately practice your programming and software engineering. Along the way, it will feel like you're going slow. But as you perfect each piece, that piece gets faster and smoother and, next time, you can move through it more fluidly.
I intended to be a mathematician and stumbled into programming. Then I intended to do computer science research, but stumbled into software engineering. Research was incompatible with my mental health (in part due to undiagnosed depression), so I started as a software engineer simply to make money. I grew to love software engineering through mastery of it.
Though, there are certainly interesting things you can do with fizzbuzz.
The best community for this is the Recurse Center. If this post resonates with you, think about applying for a batch!
Hopefully your manager does care. Sometimes they don't, and there are better jobs out there.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts and support my work, subscribe to the newsletter. There is also an RSS feed.
Want to become a better programmer?
Join the Recurse Center!
Want to hire great programmers?
Hire via Recurse Center!