2009-02-24
A core principle of error and warning messages
Here is a core principle of how and when programs should show error and warning messages of all sorts:
Error messages should only go to the people who can do something about them.
This goes double for warning messages.
(Sometimes you don't have a choice, at least in theory; if your program suffers a fatal error and you have nowhere else to log it, dumping it on the user does some moderate amount of good. Maybe.)
There's two reasons to be careful where your error messages go (or maybe three). First, it's annoying to people to get messages that they can't do anything about, and if you are dumping warning messages, you are also training people to ignore all messages from your program. Second, it's not effective in letting you know about problems, since most bystanders, confronted with a warning or an error message, will simply throw it away.
Or in short: dumping internal messages on bystanders annoys them and doesn't help you. Presumably these are not your goals.
(I find this especially inexplicable in web applications. Anything that is coherent enough to produce a nice HTML-formatted stack backtrace is certainly coherent enough to log that backtrace somewhere where the developers might actually see it, especially since most web servers have error logs.)
This doesn't mean that you need a hideously complex logging system just in order to print internal warnings or detailed error reports for your own use during development. What you should do is make those things conditional (often on something in the environment, such as a debug variable), and default them to off. Then you can turn on all of the debugging you want when you run the program, and everyone else isn't subjected to it.
(And yes, I turn pretty HTML-formatted stack backtraces on while I'm developing CGI programs. But when I put those programs into production I turn those backtraces back off or have them logged to a file.)
2009-02-17
Design versus construction
Every so often, people compare programming to something like building a house and ask why software projects can't be half as well estimated as physical engineering projects typically are. One of the many reasons that this is a bad comparison is that physical engineering is different from software engineering in a crucial respect.
The process of getting something physical constructed is generally divided into two phases: design, the intellectual engineering work, and construction, which is theoretically mere unintelligent physical labour. Thus, once you've finished the design work, the construction time can theoretically be predicted fairly well, since people have a fair amount of experience with how fast various sorts of construction go.
And generally we only talk about the construction time. The design time is implicitly swept under the carpet, partly because the construction times are usually much longer and more expensive than the design times (especially for difficult engineering projects).
Programming is not like this at all. To the extent that programming even has 'construction', things that can be done without needing to make choices and explore options, these things usually have already been automated. There is a whole infrastructure of compilers, libraries, high level languages, and frameworks that are in themselves the 'construction' (and are often done with far more sophisticated techniques than would be feasible for physical construction). This leaves programming with only the design phase; thus, there is no real 'construction time' to be estimated for a programming project.
(All of the sophisticated time estimation methods that we've evolved for software projects are best understood as attempts to predict and monitor the uncertain process of design, to guess how long it will take and to notice when things turn out to be more difficult than guessed.)