I’ve always been interested in improving my programming ability, not just my ability to write code, but also my ability to think clearly about problems and then map that thinking to efficient, working code. After all, if you’re spending more time writing code than you are thinking, you’re probably doing something wrong. Lately I’ve come across articles about how top performers like Tiger Woods, Bill Gates and Mozart put in large amounts of time and effort in their fields before they became top experts. The two most useful articles I’ve come across are Why Talent is Overrated and Outliers: The Story Of Success. There are also books from the same authors available for what I think are really low prices on Amazon. While I strongly recommend reading the articles (and maybe buying the books) the core message is really simple: to become an expert in your field of work, you have to put in roughly 10,000 hours of concentrated effort.
What is effort?
Before I go any further, let’s get clear about just what that 10,000 hours amounts to. It doesn’t mean doing repetitive grunt work and it doesn’t mean doing your work while you’re watching TV. Firstly, all of the 10,000 hours has to be devoted to actually working. You should be working with full focus on a particular task and nothing else at that time. Secondly, you have to work smart as well as hard. You need to understand what you are doing, what mistakes you are making, how they affect your performance and how you can improve. In short, you need accurate, constructive feedback and criticism. Along the same lines, it is also essential to be working towards a specific goal and making sure you are setting clearly defined milestones (as opposed to vague “I need to get better” goals).
Just as important is that your work be geared towards continual improvement. Specifically, you need to be working on problems that are just beyond your comfort level. This is a tricky balance to maintain. If the problems are too easy, you won’t learn anything new and if they’re too hard, you risk just sitting around and just getting frustrated.
Applying to programming
Programming taught in schools and universities around the world is mostly taught as if it were just another science or a form of engineering. However, unlike most other pure sciences, computer science involves a much larger element of practice. Thanks to modern technology you don’t have to wait around for your experiments to finish, you get instant feedback on whether or not your code works. This means that programming can (with some modifications) be treated similarly to performance arts like music or sport: to be a good programmer, you need to be continually practicing writing code as well maintaining a wide repertoire of techniques you can bring into play when the need arises. So let’s see how we can apply the 10,000 hour concept in order to become a better programmer.
1. Write code, a lot of it.
It’s hard to improve at programming if you’re not doing any. So pull out your compiler, dust off the text editor and get to work. The 10,000 hour mark means that you’ll be writing a lot of code. It’s important to realize that if you really want to become a top notch programmer, it’s a lot of work. If you set yourself a 5-year time limit (say all of college and then another year), you’re going looking at 6 hours a day of writing code. It’s not an easy choice, but depending on what you want to achieve, it might be worth it. For me personally, I would say that I’ve clocked about 500 hours in the past year or two, which isn’t a lot, but it’s a start. I may have done a bit more, but I wouldn’t really call all of it focused effort.
2. Make sure you’re always learning.
Just because we’re setting a number here doesn’t mean that’s the most important thing to keep in mind. You won’t be learning much if you spend 6 hours a day writing ‘Hello, World!’ in a bunch of different languages (except perhaps a cursory knowledge of I/O and program structure in the languages you’re dealing with). The best musicians and athletes out there have a variety of skills and talents they can pull out at a moment’s notice. Think about Tiger Woods and all the different places a golf ball may end up. It is essential that over the course of your work you expose yourself to a lot of different ideas.
One good way to do this is to learn new programming languages, I’d say pick up a new language every few months. There are a number of languages that you absolutely must know. C (and maybe D) for systems and down-to-the-metal programming. Smalltalk for object oriented programming. Lisp and Scheme for functional and syntactic abstractions. ML or one of its derivatives like Haskell to understand type systems well. Prolog for logic programming. A good general purpose language like Python, Perl or Ruby for day-to-day tasks and C++ and Java for all the huge amount of code out there that’s written in those languages. The list might seem daunting, but once you get started it can be interesting and quite enlightening. My programming languages course this semester has added significantly to my toolkit and in the future I plan to look into web programming, databases and concurrent systems.
3. Read other people’s code and find a mentor.
Athletes and musicians have a definite in advantage in that there are trained coaches and a large body of work regarding how to develop and train top athletes. Unfortunately computer science and most of its sub-topics are yet to develop such a body of work. We have to substitute coaches with professors and teachers and the massive body of well-written code that is already out there. Reading other people’s code is a good way to pick up new ideas and techniques, in much the same way that athletes study past games. At the same time, you’re going to have a hard time improving yourself if you don’t have a clear idea of what you’re doing wrong. It’s hard to have an honest unbiased opinion of your own work, so it’s good to have someone you can give you a honest assessment of the quality of your work and tell you if you’ve gotten any better. This is the part where your teachers and senior colleagues can help you out. If there is no one you know who can fill this role, then there’s always the Internet available to look for like-minded individuals.
4. Find interesting problems.
Let’s not kid ourselves: going through this process of continual self-improvement is going to be hard. For most programmers I know, doing hard work for the sake of working hard is not their top priority. Part of the classic hacker mindset is that we prefer to work on problems that are fun over anything else. Luckily for there us there are lots of problems out there that can help us channel our efforts while at the same time giving us tons of enjoyment in the process. Contests like TopCoder and Project Euler are a good source of practice problems and if you prefer doing something real world, there are tons of open source projects out there that could use your help. Thanks to initiatives like Google Summer of Code, you can even get paid for what you’re doing. So if you ever find yourself being pulled down by the sheer immensity of the task ahead of you, find something that genuinely interests you and start pumping out the code.
5. Set goals and keep track.
To be able to continually improve yourself, you need to set yourself goals and then plot straight courses towards them. Though it’s easy to set a broad goal like “become a better programmer”, such a goal tells you nothing about how to actually get there. Much more helpful are short term goals that target specific abilities. For the past few months my goal has been to understand more about the abstractions provided by different programming languages. For the first quarter of next year, I’m going to be focusing on algorithms and memory management techniques. Set a specific goal and then lay out an outline of subgoals that will bring you closer and closer to your goal. Most importantly, make sure you actually meet those goals: specifically, produce working code that involves the areas you’ve tried to improve in.
It won’t be easy…
but that also means that most other people won’t be making the commitment. For me, it’s slightly easier being a student: I don’t have to worry about holding down a job or feeding my kids. I can also structure my courseloads to require programming intensive courses; next semester I’m taking Software Engineering and a Theory of Computation course as well as computer organization and a Digital Circuits course. I’m just over 20 years old right now, and keeping the 10,000 hour mark means that I could become a top notch programmer by the time I’m 25, i.e. about halfway through graduate school. That’s still a few years late, but better late than never. 6 hours a day for the next five years is a hard commitment and I can’t say that I’ve ever done anything quite like it. But considering that I really can’t see myself doing any other kind of work (except perhaps writing) it’s a commitment and investment I’m willing to make. I had better go and get started.