I just read three really good essays on how programming is very similar to dreaming and why it’s important that programmers not be woken up from this trance-like state unless absolutely necessary. Here are the articles and I encourage you to go take a look at them yourself. If your job involves interacting with programmers in any ways, they’re a must read:
It might seem strange to compare programming to sleeping or dreaming. After all, sleeping is meant to be relaxing and refreshing, while programming can be rather strenuous and mentally draining. However, the similarities are hard to ignore. For most people, it takes about 90 minutes after falling asleep to actually enter REM-sleep, the portion of sleep where you actively start dreaming. REM sleep is also very easy to disrupt and wake up from. Similarly when programming it takes a certain amount of time to get into the state of flow and reach your peak effectiveness. Any break in either REM or the programmer’s flow state requires a siginificant amount to recover from.
Being a college student with a full load of classes and activities, I’ve always been interested in finding the most effective way to write good code in the shortest amount of time. I’ve been spending the last few days working on an individual C++ project and thanks to that I’ve been able to remember some of the things that I noted in the past, but ever actually put into words. I’m going to try to put into text some of the things that I’ve learned are important for programmers to understand and put into practice.
Firstly, writing code, writing good code, doesn’t happen in bursts. Not unless you’ve been thinking about the problem (or something similar) for the whole day (probably more). Don’t get me wrong here, epiphanies and ‘aha’ moments do happen, but only if there’s been a substantial amount of time, knowledge and mental effort already existing. You can’t have the final piece of the problem fall into place unless all the other components are there already. Complementary to this, brute force doesn’t really work all the time either and randomness certainly doesn’t either. Programming is intelligent work. If you come across a problem, it’s a bad idea to start by throwing every solution in the book at it. Spend some time to lay out a careful plan and then execute. Use tools like debuggers and profilers. Over the past two years I’ve seen more than one fellow student (including myself at times) get frustrated and start changing code at random, hoping the problem will somehow disappear. Sorry, it doesn’t work that way and you know it.
Of course, just because programming requires intense sustained concentration doesn’t mean that you should make marathon 10-hour non-stop coding sessions a daily occurrence, especially if you’re a student doing a bunch of other things at the same time. To steal a line from my professor, there’s a reason coding death marches are called death marches. Be careful to pace yourself. When you’re on a roll it’s easy to glide from one problem to another, slaughtering your bug list in the process, but do try not to get carried away. At the very least, stand up, close your eyes and stretch once an hour. Also make sure you keep a full bottle of water near you at all times. Yes, I said water, not a caffeine drip. Please don’t flood your body with stimulants more than once a day. All that being said, distractions are dangerous, which is why you need to be proactive in avoiding them. Take breaks on your time. Every time you finish a major milestone, try to rest for a minute or so. I’ve found it’s possible to take a break without interrupting my flow state if I schedule the break myself. On my project I took a little walk break when I finished a class and when I’d finished a group of related tests.
While you’re scheduling your own breaks, make sure to eliminate or at least minimize unexpected interruptions. A room with a door that can be closed is good. A “Do not interrupt” sign with a board next to it for messages can be useful too. For students in labs, that’s not really an option. However, even if you do have to work in an open workspace, there are some things you can do. Sitting away from the door and facing a window or wall helps. Earphones are usually a good idea for keeping out sound, and if you’re an audiophile ( I think many programmers are) all the better. Also don’t feel committed to answer every time someway waves to you. Sure it’s not perfectly polite, but you’ll working better if you focus on your task and the person who waved to you will probably forget in an hour anyway. And please take measures to avoid checking email or Facebook or Twitter every few minutes.
Four: Cowboy coding is bad. (I’m not sure if 4 is the right number, it seemed a nice round number to me.) It’s one thing to have faith and confidence in your coding abilities. It’s another thing to rush into a battle without surveying the battlefield first. It’s important to read the problem description carefully and have some amount knowledge about the problem domain. If you just jump in and start coding, you’ll find yourself making a lot of silly mistakes and false starts and end up wasting a lot of time and effort on clean-up and rewriting what could easily have been running code the first time around.
Paul Graham has a very nice (and similarly themed) article about how programmers work. To be good programmers we need to be able to keep the problem space in our heads, just as good mathematicians can manipulate complex sets of equations and formulae in their head. In fact, Princeton physicist Edward Witten is known for manipulating whole blocks of complex equations in his head while staring out the window. This doesn’t mean that you need to memorize every line of every file you’re working on, but it does mean that you shouldn’t be constantly looking through API documentation to find what you need. As you can imagine, doing this needs more than just mental aptitude. No matter how good a hacker you are, you’ll need some time every time you start to bring everything up into your mental RAM so to speak. You also need to be proficient in the language and toolkits you’re using. This is easier to achieve if you use roughly the same set of tools for most of your work. This is also the reason that a lot of great hackers seem to prefer a highly customizable editor like Vim, Emacs or TextMate. Having powerful text editing functions and hooks into other programs just a few keystrokes away is incredibly more powerful than having to navigate a rigid point and click GUI.
The process of writing good code isn’t an easy one. As I’ve tried to explain, there’s more to the process than just sitting down with a problem statement and pumping out the code. However, while getting into the zone and staying there requires a lot of care and caution, once you’re there, the process can be rather relaxing. I’ve realized (and I’m sure you have too) once you’re in the state of flow, you can stay there for hours at a time without thinking about anything else. In fact, no matter how much other stuff I might have on my mind, everything disappears when I get started coding. This may be true of other activities that require deep concentration, but the truth is, I’ve never found anything else that requires as much concentration, but is as enjoyable. However, the flip side is that once I’m done, I’m mentally exhausted and I can’t do anything else that requires thinking until I’ve taken a long break (physical exercise helps). Yes, it’s a compromise, but if I’m going to go to all that trouble to write some good code, a little tiredness is acceptable.
As an ending note, programming certainly isn’t for anyone who doesn’t enjoy working quietly alone. But we already knew that, didn’t we? As for the rest of us, I hope this post agrees with some of the things that we’ve all seen in our work. Have fun programming in your dreams.