I was surprised to find that lisp had a more powerful way of dealing with errors than exceptions (which I had previously assumed were state-of-the-art in program error handling). Lisp conditions are similar to exceptions, except that the condition handler is able, if desired, to resume execution to the erroring function by invoking one of any named 'restart points' declared by that function.

To understand why this is important, the Seibel book illustrates the case of a line parser function. This function is given a file to parse from and returns a stream of parsed tokens. The error occurs when the parser hits a line that it can't parse. At that point, the program has a number of options, including:

(1) Cancel parsing the file all together (2) Ignore the line and continue (maybe logging an error) (3) Fix up the input in some way or emit a marker in the parsed token stream.

The problem with the exception model is that an exception handler in a calling function is only in the position to do (1). By the time it receives the exception the stack has been unrolled and its associated state lost. This means that if the program wants to do any of the other possibilites the exception handling implementation code needs to be in the parsing function itself, which strongly couples its behaviour with the rest of the program.

In lisp the condition handler further up the stack can do any of the 3 options, including e.g. logging the error and then invoking a 'skip-log-entry' restart, or maybe the 'use-value' restart passing it a valid value to put in the token scheme.