Learn Patiently, Execute Impatiently
When executing on something, the most important thing is your momentum. It’s a swinging motion — moving vine-to-vine — going from uncertainty towards some roughly-defined endpoint. You can start with a rough sense of the direction you’d like to move, but trying to pick all the vines you’re going to swing on ahead of time is setting yourself up for disaster. You can never understand a project that far ahead.
The opposite of execution is learning. This is building knowledge that stays with you for a lifetime. It’s understanding built from first principles.
Lately I’ve been attempting to recognize the differences between these two modes. My hypothesis is that they can’t operate side by side most of the time, so understanding which mode you’re in is crucial.
Execution is about moving to the highest feasible layer of abstraction. Don’t reinvent the wheel. If there’s an API that does what you’re looking for, use that. If there’s a tutorial that shows you how to do what you’re attempting, follow that. Deal with the problems of trying to glue together a misshapen jigsaw puzzle. Don’t try to build the puzzle pieces from scratch. Use every available tool to maintain momentum.
Learning is moving to the lowest layer of abstraction that still provides value. If you’re writing software it’s understanding operating systems, compilers, math — the roots of the tree of abstraction.
Attempting to mix these two is where the “shaving the yack” comes from. You encounter a problem or a lack of understanding at a higher level, and find yourself burrowing down through layers of abstraction attempting to find a bottom where you can fix the problem. The issue is you rarely find that bottom — you’ve entered learning mode and will always find some new unknown deeper down the abstraction tree that feels like it will solve the problem.
Understanding when you should execute is the simpler of the two. Are you trying to create something with an endpoint? Then you’re executing.
Understanding when and what to learn is the more subtle half. There are two guideposts I’ve found are most valuable: experts, and experience.
Experts can provide the roadmap of what they’ve found is worth learning. But be sure that you’re looking at someone doing work similar to what you actually want to do. Different outcomes have different roadmaps.
It’s easy to discount the recommendations of experts since their paths were forged in a completely different time with different tools. Problem sets do shift over time, but I suspect they shift less than we think. Computers to a certain extent are still just a read/write heads. This is why computer science students take computer engineering courses. It’s a level of abstraction so far below what they normally work on that it often feels pointless. But enough people down the path of expertise know how that lower level understanding affects their execution. They sense how that knowledge allows them to improve their ability to execute.
In addition to the experience of others, inspecting your own experience is the other half of the puzzle. How many times do you really come across a problem? How often does your lack of understanding really affect your ability to execute on something?
Chances are that the biggest hole in your understanding isn’t the one you came across just now. Let knowledge-gaps naturally bubble to the top of a mental checklist over time — use that to determine what you should invest time in learning.
Execution without learning can feel very efficient. This is software-development-via-Google-search. You encounter a problem, hope someone else has encountered the problem before and written down their solution. If they haven’t, well, you do something else. However, endless execution without learning is a shaky tower of knowledge. The higher up the tree of abstraction you go, the more rapidly things change. This is where people get the sense that programming is reinventing itself every six months — your head is stuck in the firehose of new programming languages, frameworks, and tools. You’re bobbing on the rough seas of abstraction without an anchor in deeper waters to hold you down and give you a sense of perspective.
Learning without execution, on the other hand, is largely pointless. There is the thrill of new knowledge, but without execution your understanding remains abstract and half-formed. Most knowledge should encounter the harsh constraints of the real world. If it doesn’t you’ll probably find yourself in the comments section of an article arguing about which programming language is best. That’s fine, but, you’re mostly spinning your wheels.
As with all things the key is balance. This framework is not an answer to a question, but it’s a potentially helpful mode of inspection. It helps me explain times I’m working when things feel not-quite-right. I’ll find myself down some two hour rabbit hole on a tutorial for some low level computer graphics concept while trying to fix what should be a simple bug (too much learning while I’m trying to execute). Or I’ll find myself banging against some math concept for years that never quite clicked in school (not taking enough time to learn). I’ve been in pure execution mode for the last 2 years, and it’s been refreshing giving myself permission to focus on learning again. But as always I know the clock is ticking before I’ll have to take that learning and go execute on something.