Dialects and Compiler Warnings
My last two notes (1, 2) have centered on the notion that different programming communities use language differently, and that it is a good idea to try to write programs in a style that your community will understand.
Some programming communities use this notion as a rationale for enforcing a uniform programming style. That practice has both advantages and drawbacks. One major drawback is that members of such communities are really programming in a local dialect. Not only is the dialect usually not completely written down, but it may vary from one community to another and from one time to another.
One reader disagreed with me about the disadvantages, saying:
I think that so many readers will agree with this sentiment that there is no need to discuss the arguments in favor of it. However, I think it has some subtle disadvantages that deserve attention.
Perhaps a story will illustrate one of the disadvantages. I once talked to someone who threw a bachelor party for a friend at a restaurant. When it came time to pay the four-figure bill, his credit card was declined. When he phoned the credit-card company to discuss the problem, he learned that they would not approve that big a charge at a restaurant, even though it was within his credit limit, and even though he could have spent that much money at a jeweler. He had to borrow money from the friends he had intended to treat.
This embarrassing episode is an example of an undesired side effect of enforcing a dialect — in this case, a behavioral dialect. Such enforcement effectively prohibits behavior in practice that is acceptable in principle. In order to find out what behavior is actually accepted, one must ask permission — and because the rules might change from time to time, one must ask often.
Now let's look at the analogous situation in programming. If there is a rule that your programs must compile without warnings, then you are really programming in a language that is defined by your compiler. Not only that, but it is defined by the particular version of your compiler. Moreover, using compiler flags to suppress warnings won't really do, because the precise behavior of those flags is apt to change from one release to another as well. If a new release of your compiler has new warning messages, you may have to rewrite your code to avoid them.
This situation also affects compiler writers, because putting a new warning message into a compiler may force developers to rewrite large amounts of code to avoid the new warnings. I have had compiler writers tell me that they would not introduce new warnings because of the amount of forced rewriting that would ensue.
Here's the pattern that I think is the source of much of the trouble:
- Someone identifies behavior that is sometimes undesirable.
- Automated tools are developed to detect such behavior.
- Organizations prohibit such behavior — as identified by the tools — completely, regardless of whether it is desirable in its particular context.
It is hard to argue against any of these three strategies in isolation. Particularly, in (3) there is a strong reason to prohibit the behavior completely instead of making individual decisions — the alternative is constant bickering about individual cases. Nevertheless, the long-term result is to channel people's behavior into ever more complicated dialects.
In a sense, 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. Perhaps programmers who spend a lot of time reading and writing programs tend to care more about understanding those programs than they do about understanding the rules that they are using to decide what to write and how.