I like to find things out to add them to my mental intuitive decision-making framework. These “factoids” bring more data points and evidence to the surface to strengthen the result. The big “but” is while learning new facts is enjoyable, the result is not as much improved as I’d like to believe.
While the knowledge-gathering activity is useful for writing by sparking unexpected associations, it falls flat for skill-based activities like software development. When learning a new programming language or a new paradigm, I try to reach for what I call “thinking like an expert”. I read a lot quickly, including advanced topics, to avoid making the novice mistakes. Most learning material starts slowly (which is not a bad thing per se) and skips over many concepts or syntax you will often see in real code. Instead of learning simplified coding, I jump straight to code an experienced developer would write.
It works to a degree. The deep dive creates a lot of ephemeral knowledge that needs reinforcement, otherwise it quickly disappears. As I mentioned in “Physical education”, the brain creates many new, tentative connections, but then you have to immediately put them to use and let them grow. After I’ve read a lot I must write a lot of code, or I’ll lose most of the knowledge.
The truth is usually I start working on something only to be blocked by indirectly related problems that I can never predict — and I’ve been through the cycle many times. The dev environment doesn’t work, the library you want to use turns out difficult to integrate, the language behaves differently than you expect on a metalevel that has not been described enough in the books… Meanwhile, your newly acquired knowledge evaporates from your mind alarmingly quickly. The result is that by the time I get to implement what I’ve read, I need to read about it again.
So far, at least with learning programming languages, what works best for me is to:
- Read one or more comprehensive texts that cover all aspects of the language, including expert-level patterns. I don’t study this stuff closely and read it quickly, almost skimming — I know I’ll forget more than half of it anyway. Being aware that these concepts exist helps eliminate unknown unknowns.
- Start working on a real project immediately instead of solving toy problems. They help you learn the basics, but a real project has enough basics to learn them and is more engaging.
- Solve the next immediate problem, and only that. Trying to solve everything at once only makes you confused, but building up your project solution by solution, eventually you can ship it. Every aspect of the project can be improved, and while doing it you’re writing “real code” in the context of a larger codebase.
Gradually you learn the basics and build up to more advanced concepts (revolutionary, I know). The difference from regular “start with X language” tutorials is learning about the advanced concepts first and using them sooner (but not immediately). My theory is this helps write decent code earlier than otherwise.
That’s exactly how I picked up Go again last year and to work on DDPub, the engine this website runs on. Since then I’ve used Go in several other projects and jumped straight in every time. For me, trying to figure out the solution to a specific problem results in much better retention than simply knowing all the advanced things without a way to use them.
This is all somewhat similar to the Feynman Technique:
- Study a topic
- Explain the topic to someone else in as simple terms as possible (in this case, to a computer through programming)
- Identify gaps where your explanation doesn’t work (i.e. you can’t implement something because you don’t know exactly how)
- Improve your understanding and try again
You cannot be sure you truly know something until you try to explain it — whether through writing, talking, or code.