July 30, 2021
I was talking with a friend today who asked a question I’ve been asked many times before, which is “How do I get to the next level?” He’d learned programming, and he’s pretty good at it; but he knew he was missing a lot of core computer science, and he really wanted to know how to get what he was missing.
So I thought about it — and it’s a question I’ve thought about a lot before, because people keep asking. So if I was to suggest a good path for learning to be a good coder, it would likely go something like the sequence below. There’s probably room for fuzziness and reordering in the later steps, but I’d still recommend a lot of these, because they really do all make a difference, and they’re things I use every day.
- Learn important algorithms and data structures. You’ve done lots with arrays and maybe maps or hash tables by this point; but now you need to expand your repertoire and learn about lists, trees, sets, set theory, heaps, graphs, and other ways of storing and organizing information. When you’re learning these, think a lot about things you’ve already made, and think about ways you could have done it better with the new tools in your toolbelt.
- Learn a flavor of assembly language. All of this stuff is high-level so far; but what’s underneath? How does the computer really work? This is your chance to find out. Assembly can be a bit hard, but once you understand it, the high-level stuff will seem more obvious. (Someday, I swear I will finish writing “Sean’s Assembly Intro,” and describe a way to learn assembly with a lot less pain.)
- Learn C. C is often called “high-level assembly language,” and after learning assembly, C will be surprisingly straightforward. You’ll realize that references are just pointers, and pointers are just numbers, and all of those data structures you learned are just different ways of looking at memory.
- Learn about compilers. Compilers seem like magic — but studying compilers will reveal the man behind the curtain, and show you what his limitations are too. This will also give you a set of new, very powerful conceptual tools for transforming data into other data — ways of thinking that many programmers never learn.
- Learn a strongly-typed language. Strong typing can help clarify and purify concepts that until now likely have been pretty fuzzy in your head. TypeScript, C#, F#, Haskell, Ocaml, SML, even Python with mypy. Spend enough time doing this that you, too, want to try to explain to everyone else what a monad is.
- Learn Lisp. Lisp has been around since before almost every other language in use today, and there’s a reason it’s still around. Even if you never write any Lisp professionally, learning it will change the way you think about coding — and you’ll realize just how much every other language you’ve studied stole from it.
- Learn about data compression. Data compression seems like magic — but it too is just a set of rules and patterns. You’ll learn about information density and entropy, and what lossless and lossy really mean, and ways of dealing with specific kinds of data, and what the limits are on how much data can exist; and then you’ll start to ask critical questions about how you’ve been storing data in your own software.
- Learn automata theory. By this point, you know how computation works, right? The machine executes instructions, or maybe reductions, and that’s all there really is to know, isn’t it? Learning automata theory will change how you understand computing in general: State machines, push-down machines, and Turing machines will give you powerful conceptual tools to explain how computers can — and can’t — work.
- Study others. Last, but not least, this entire time, you should have been not just coding, but also reading other people’s code — and thinking critically about it. How did they solve problems? What worked well? What didn’t? What techniques were good? What were obviously bad? Great novelists don’t just write books — they read lots of books too, and great programmers should read just as much code as they write.
There’s plenty of other stuff worth learning, of course! There’s scientific computing, networking, 3-D graphics, GUIs, operating systems, parallel computation, garbage collection, design patterns, image manipulation, and a thousand other categories of human knowledge. But if you do the ten steps above, you will at least have covered a lot of concepts that will keep coming up again and again and again, and if you’re a coder, very few of these — if any — will you ever regret having spent your time learning.