The Tension Between Reading and Writing Programs
I would like to discuss two interesting comments about last week's article. First up:
Of course programmers try to understand the programs they are working on, in terms of how those programs are currently written.
But after that, they want to apply their judgment. Does the current code smell? Is there a better/easy way to write this, with minimal risk? Is how it is now acceptable, good enough?
And regardless, programmers always want to understand the rules they are using to decide what to write and how. Isn't that the definition of a programmer?
My experience is that some programmers want to understand their programs, and others don't. I was once at a talk by Jerry Schwarz, the author of an early version of the C++ iostream library, where he described the following debugging technique:
- Pick a part of your program that looks like it might be related to the bug that you're trying to find.
- Change that part of the program somehow. Run it again.
- If that fixes the problem, you're done. Otherwise go back to (1).
Much of the audience laughed nervously at this description. When he added:
This technique is known as rapid prototyping
the audience exploded in laughter and applause. I submit that this event shows that his description struck an all too familiar chord with the audience.
As another example, I've encountered programmers who take the view that once a program has passed all of its test cases, it's time to ship. There's no point in trying to understand why the program does what it does, or to look for ways to simplify it. If it turns out that the program works only by coincidence, the fault is not in the program but in the tests, which were proven inadequate by the fact that a broken program nevertheless passed them. Programmers who adopt this viewpoint probably do not think that understanding the programs they are working on is necessary or even desirable.
So although I am willing to agree that some programmers try to understand their programs, I claim that there are some who don't care much, so long as the programs appear to work.
Now for the other comment:
…I'd suggest that static analysis and coding standards can be used to make programs more readable and maintainable. …By prohibiting some practices — and using compile-time tools to do so — we can encourage correctness, readability, portability, and maintainability… [S]aying that one should prefer the lowest common denominator in a language (viz., the bare standard) seems to ignore additional information that is available and potentially quite valuable.
I did not say that "one should prefer the lowest common denominator in a language." What I said was:
I think that there is a tension between the complexity of our programs and the complexity of the dialects that we use to write them.
In other words, I identified two desires pulling in opposite directions:
- the desire to simplify programs, and
- the desire to simplify the rules that constrain how to write programs.
In other words, there's a conflict between making programs easy to write and making them easy to read. I did not say that either of these desires was to be preferred to the other; merely that they both exist and oppose each other.
Every time we adopt a rule that is intended to make programs easier to read, we increase the burden on the people who write those programs, and vice versa. To the extent that people spend more time reading code than writing it, this may be a good tradeoff — but carried to extremes, it may make things worse, not better.
Here's an example that I saw long enough ago that I no longer remember where I saw it: Once upon a time there was a programming shop that decided to require its programmers to document every subroutine that they wrote, and to check it into the global code library. By making such code documented and available to anyone, they would save programmers the effort of redeveloping it from scratch.
The effect of this requirement was that programmers who wanted to write short subroutines for their own use resorted to copy-and-paste instead, in order to avoid the documentation requirements. In other words, the rules got more complicated, so programmers tilted their own efforts toward avoiding the complexity that affected them personally. Can you blame them? Isn't that behavior obvious in retrospect?
More generally, I think people tend to be more interested in what they themselves do from day to day than they are in what other people do from day to day. So programmers who write a lot of code want code to be easier to write, and programmers who read a lot of code want it to be easier to read. There's that tension again.
The point I'm trying to make is that the tension exists, and that there is not always a single best way to resolve it. Like so many other aspects of software, it's an engineering tradeoff.