3 ms·
I'm afraid to sound like a negative type, but to me this example is simply a callback? The described EMPLOYEE-WORKING-DURING-HOLIDAY is akin to a system has a
by pierrebai 6y ago
I'm afraid to sound like a negative type, but to me this example is simply a callback?
The described EMPLOYEE-WORKING-DURING-HOLIDAY is akin to a system has a slot to register a callback (or signal which can be connected to receiver, to use a Qt-like design) which can handle the situation or decide raise an exception.
Again, I understand that it might be attractive to have a single unified system to handle the different possible situations instead of separate systems. I find it hard to imagine a case where the decision to be an exception-like, callback-like or restart-like is chosen dynamically at run-time by any or all participants. And like I said, I' d be afraid that if such a case come up, it would make understanding the design harder, not simpler.
For example, as much as Qt signal/slot mechanism is powerful and flexible, I've found that when used fully, it makes understanding the code hard because it becomes impossible to know what will happen when a signal is raised because the handling is so well uncoupled.
- phoe-krk 6y agoYes, you are correct! (And you don't sound negative just yet; skeptical, if anything.) The mechanism of handlers is literally a mechanism of dynamically provided callbacks. I draw the parallel between condition handlers and callbacks/hooks in the body of the book, too. The difference is the fact that Common Lisp has facilities that allow two things: choices of what and how to proceed and flexible non-local returns. The callback is allowed to list all recovery choices that are present in a given dynamic environment; they are established dynamically, just like handlers, and therefore can be provided fully from outside. For instance, a handler/callback can invoke a choice named CONTINUE if it decides that absolutely nothing needs to be done and the validation is safe to proceed. The validating code doesn't need to know why exactly that choice was taken. Or, if it notices that e.g. it needs to convert a timesheet from version 3.0 to version 4.0, it can call a conversion function on the timesheet object and invoke a choice named REVALIDATE, passing the converted timesheet as an argument. Note that the validating code doesn't need to know about any details of the conversion routine! It only needs to provide a means of restarting the validation by establishing a REVALIDATE choice. Or, if it decides that the situation is hopeless, it can signal an error of its own and defer the responsibility of handling that situation higher up - all the way to the system debugger, if necessary. The validating code doesn't need to know about any details of why an error was signaled! That's a ton of modularity that we've just given there. These choices are actualy named restarts in Common Lisp. I purposefully name them choices, though, as I introduce them in the book.
- db48x 6y agoThey are callbacks, but when they return they don't return to you. Instead they return back up the stack to whoever called the function that signalled the condition.
- phoe-krk 6y ago> Instead they return back up the stack to whoever called the function that signalled the condition. Not necessarily. They may return to any point on the stack that has been "announced" as a valid return point. One can compute a list of these return points, choose which one to utilize, and under which conditions. That's what constitutes the power of restarts (and non-local exits) in Common Lisp.
- kazinator 6y agoWhen a condition handler returns normally, it is understood to have declined to handle the condition; the search continues for another handler.
- kazinator 6y agoCondition handling is an evolution of callback-based handling methods. A condition handler is a kind of callback. The way it is registered and invoked is different. It doesn't have to be passed down as an argument. It is tied to an exception type, which is linked into an inheritance hierarchy that allows for flexibility in searching for a handler. A handler can decline to handle an exception simply by returning; then the exception search can find another handler.