One of the things I've realized is that I love to teach this stuff. I'm not talking about syntax and "what is an object" and all that stuff; I'm talking about stuff like:
- Programming is simultaneously much easier and much harder than you imagine. The trick is to determine what your mind and society just convinces you is hard (before the fact) versus what ACTUALLY separates average or beginner coders from the masters.
- In anything but the smallest script or test application, architecture is EVERYTHING. But architecture is more of an art than a science. It takes more skill than most imagine to figure out what to name things, how few or how many "buckets" to construct such that current and future functionality fits in the right bucket, how to recognize when your current architecture needs to be amended or replaced, yet how to restrain yourself from designing a cathedral when all you need is a two bedroom apartment, and how to develop the discipline and leadership to keep other programmers (and yourself) within the architecture that you've laid out.
- Along the same lines, how much easier it is to code something when you have thought through the overall concepts in your head, not in the world of your favorite programming language.
- The skills you need to learn new programming languages in minutes or hours rather than days or weeks.
- It is fun and enlightening to understand what's happening at the bits, bytes, and machine code level at the same time you understand what's happening behind the layers of abstraction that your programming environment provides. By connecting concepts "all the way down", I've seen many wonderful "a-ha!" moments.
- The notion of "audience". Just as you must design your top level interface to the audience of your end-user, so must you design the layers of your code to the audience of the programmer-user who will use that layer to implement higher layers. Truly understanding that programming at each layer is about designing the best, most usable interface you can for the layer above you is, I've found, one of the quickest routes to respecting and appreciating architecture.
- The true barriers to becoming a great programmer are not often the technical ones. Things like algorithms, idiomatic coding in a certain language, database design, performance analysis, and design patterns are challenging and are worthy to learn, but they are almost unlearnable in a vacuum. When you're just getting started, the same can be said for just learning how to program at all. In my experience, you MUST have a project in mind. You can read all the "21 days" books you can find, but in the end if you don't have an idea that you just can't wait to implement, you'll be sitting there with a blinking cursor and nothing to type but the examples in your books and tutorials. I don't care if it's Space Invaders, you have to have SOMETHING in mind.
- Debugging is often a more important skill than coding. You must be able to shake all superstitions and approach problems from a rational basis. Just like an experimental physicist, you have to learn how to form reasonable hypothesis, understand what would falsify them, and then go about doing so in a methodical fashion (in a process that often looks a lot like binary search). I still occasionally make use of fancy graphical debuggers like those in Xcode and Visual Studio, but the more I studied and mastered the art and science of the debugging process, the less I relied on those things. Nowadays, it is often faster for me to debug a problem with nothing but print statements. I also find debugging to be extremely enjoyable rather than a necessary chore. I think it's because of the "gather evidence, hypothesize, test, iterate" cycle.
- In the end, programming is the reification of "thought structures". I think this is what I find so appealing about the craft: it's the closest we have to magic. When you truly learn to create and reason about these structures in your mind and in your heart, and then learn to translate that into the magic words of your programming language, you will be on your way to becoming a master (or at least be able to create something useful of which you are proud).