Saturday, March 19, 2011

Exceptions

Exceptions. It's a part of programming that all of us have dealt with at one point in time or another. However, there is some disagreement as to the usefulness of exceptions or if they even should exist. Here's what I've discovered through reading a number of different articles.

First, there is a concern about speed. Some say that exceptions are slow and error codes should be used instead. However, it appears that while yes, checking an error code is faster. However, that's comparing checking a single error vs. handling a single exception. In reality, you'd probably have to check a number of errors every time a block of code is run vs. handling an exception only when it occurs. It is this that some people, in particular the designers of the D programming language, state is a true benefit of exceptions from a performance standpoint: since your normal code does not have to check for error conditions, it will run faster. Benchmarks that I read recently confirm this.

Second, exceptions make it harder to understand what happened. The issue here is that handling an exception is like a goto to a random spot somewhere in a program. If my understanding is correct, when an exception occurs, the program will unroll up the stack and display, essentially, the path from the program start to where the exception occurred. This really is a concern as most people are pretty lazy. I've worked on projects where exceptions are bubbled to the top of the program and the state of the method where the exception occurred. I've seen this numerous times and while it's useful to know where an exception occurred, it doesn't really tell you why. This is especially annoying when the code that threw the exception is in a library that's not yours.

What I like to do is if I know an exception can occur, I'll log the inputs to the method and, if necessary, any other related variables that can let me know what occurred. And I'll do this as close to the exception as possible. If this isn't done, you can't really know what happened. It's unfortunate that, at least in my experience, I'm the only one who's really done it.

Lastly, exceptions are supposed to be cases where something happened during the execution of the program that is not something that is expected. Errors are cases where something isn't correct, but is expected to occur. Divide by zero is an error in most cases as chances are, it's due to user input vs. something else in the system. A null pointer in a language like Java which doesn't expose pointers to the programmer is an exception in most cases.

The key is really is it something that causes program termination or is it something that is expected and can be handled. If it terminates the program, throw an exception. If you can and want to recover, check for the condition. Exception handlers are generally considered to be a poor method of doing something conditionally.

Back to the big issue, how do you properly capture an exception. Relying on the programmer to do it is really a poor solution as programmers are lazy and not always in a good way. I thought about this while traveling and I believe the solution is to have the language automatically log everything it can about the current state of the program to a file. It will make things easier as it will allow the programmer to know exactly what went wrong with ease.

In fact, the tool chain should do as much as possible for the programmer as it will make the programmer more efficient and also do common things that the programmer should be doing anyway.

With respect to SPL, this is the behavior that should be part of the language. If done right, the programmer will never have to worry about exceptions as it will automatically be properly handled by the language itself. The programmer can then focus only on what they can control vs. what they can't.

Labels: , , ,