I hadn't seen Robert Read's How to be a Programmer: A Short, Comprehensive, and Personal Summary until recently, when it was linked to by some random web newsletter that I follow.
Although it suffers somewhat from being overly long, there is still a lot of wisdom in this essay, and it's certainly worth the time to read.
I suppose I was hooked when he started with perhaps my favorite topic: debugging.
Debugging is the cornerstone of being a programmer. The first meaning of the verb to debug is to remove errors, but the meaning that really matters is to see into the execution of a program by examining it. A programmer that cannot debug effectively is blind.
I like that much of Read's advice is very practical. For example, when talking about debugging, he notes that you can use a debugger, but that there are many other ways to debug: reading the code, reading log files and traces, inserting print statements, adding assertions to the code, etc.
Since debugging is one of those activities where the goal is not to win a beauty prize, but to get the job done, a practical approach is the only sensible way, so I knew Read spoke from experience already.
It's also interesting to see how Read approaches a problem I've seen many a time: fear of making things worse:
Some beginners fear debugging when it requires modifying code. This is understandable---it is a little like exploratory surgery. But you have to learn to poke at the code and make it jump; you have to learn to experiment on it, and understand that nothing that you temporarily do to it will make it worse. If you feel this fear, seek out a mentor---we lose a lot of good programmers at the delicate onset of their learning to this fear.
Or, as my old friend Tom always says, "We call it software because you can change it."
Of course, some bugs are simply hard, and it's a measure of Read's real-world experience that he's seen those before, too:
If you can't reproduce it, set a trap for it by building a logging system, a special one if you have to, that can log what you guess you need when it really does occur. Resign yourself to that if the bug only occurs in production and not at your whim, this is may be a long process. The hints that you get from the log may not provide the solution but may give you enough information to improve the logging. The improved logging system may take a long time to be put into production. Then, you have to wait for the bug to reoccur to get more information. This cycle can go on for some time.
How true this is! I have several bugs, important ones that I'm enormously concerned about, that I'm deep into this "cycle" with, myself. A few of them have been plaguing me for years. Sadly, one of the only ways you know you're working on an important body of software is when you encounter situations like these.
If it were an easy bug, we'd have fixed it by now. The hard bugs are the only ones left.
Read's essay, like any deeply personal essay, is uneven. He spends a lot of time covering topics such as:
- How to Recognize When to Go Home
- How to Stay Motivated
- How to Disagree Honestly and Get Away with It
- How to Tell People Things They Don't Want to Hear
- How to Get a Promotion
- and How to Deal with Organizational Chaos
But Read will get no friends for making a suggestion such as:
commonly, some stressed-out person who does not have the magic power will come into your cube and tell you to do something stupid. If you are really sure that it is stupid, it is best to smile and nod until they go away and then carry on doing what you know is best for the company.
This, of course, is exactly why software engineers have the prima-donna reputation that they do.
And it's not clear to me if Read even realizes what he's saying. There's no hint that this is tongue-in-cheek, or that he understands the implications of his suggested approach to the cacophony of opinions that characterizes software development, and how it risks branding the practitioner as one of Those Guys You Never Want To Work With Ever Again.
Yet it is also valuable advice, if you understand how and when to use it properly.
I suspect that Read and I would find ourselves to Disagree Honestly on many more topics. For example, I don't think he gives anywhere near enough credit to the writing of tests, which is the one technique that I've spent the most time developing in my own repertoire over the last decade, and which I think remains the most underused technique among the stellar programmers that I know.
And he almost completely overlooks another crucial topic, in my opinion: acquire tools, learn to use them, and practice using them well. Here, I'm thinking about tools like editors, code analyzers, bug trackers, test harnesses, performance monitors, shells and scripting tools, code coverage reports, memory leak detectors, SCM systems, and the like.
Read is at least honest about his weaknesses in this area, noting, for example, that
I was late to appreciate the benefits of source code control systems but now I wouldn't live without one even on a one-person project. Generally they are necessary when you have team working on the same code base. However, they have another great advantage: they encourage thinking about the code as a growing, organic system. Since each change is marked as a new revision with a new name or number, one begins to think of the software as a visibly progressive series of improvements. I think this is especially useful for beginners.This is all well and good, but it only begins to touch the power of what you can do with a source code control system. Code archaeology, project branching, configuration tracking, bug bisection, system organization, code security, build automation; all these techniques and many more become possible once you start to learn how to really use your source code control tools effectively.
Similarly, one of the breakthrough moments for me was a point where I was, frankly, stumped on a subtle and elusive problem, battering my head against the same walls. A wise programmer of my acquaintance, when I approached him for advice, took a holistic view, asking questions like:
- From the historical records of your build automation system, can you tell when the problem began to appear? what platforms and configurations it appears most commonly on? what patterns appear in the problem occurrences?
- Can you correlate the problem to performance behaviors using your performance tools?
- How has the configuration of your test systems changed since the code was written?
- What shows up when you search the bug tracking database for that message?
- What is the history of that bit of code? When was it last modified, why, and what bugs were being fixed? Do you have tests for those bugs? Can your coverage tools tell you if they're exercising that code?
Now the skillful workman is very careful indeed as to what he takes into his brain-attic. He will have nothing but the tools which may help him in doing his work, but of these he has a large assortment, and all in the most perfect order.
But Read's essay is over a decade old; I'm sure that his views have changed during the years, and perhaps if he and I were to meet now, we'd find that we agree on more things, and disagree on fewer.
If you're considering a career as a programmer, if you know a programmer and find that you must spend a lot of time with her or him, or if you're just curious about what goes through the mind of a programmer, Read's essay is well worth your time.
And if you're already a programmer, and want to become a better one, I'm confident that you'll find lots of ideas to chew on in Read's essay; self-improvement never stops, and there is always more to learn.