The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
The bright side of exceptions
The Lisp Condition System
Didier Verna
didier@lrde.epita.fr
http://www.lrde.epita.fr/˜didier
http://www.facebook.com/didierverna
@didierverna
ACCU 2013 – Saturday, April 13th
1/20
The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
What is an exception?
The Java
TM
Tutorials (docs.oracle.com)
Definition: An exception is an event, which occurs during
the execution of a program, that disrupts the normal flow of
the program’s instructions.
When an error occurs [. . . ]
If the runtime system exhaustively searches all the methods
on the call stack without finding an appropriate exception
handler[. . . ], the runtime system[. . . ] terminates.
Unfortunately, “exception” really means “error”.
2/20
The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
Benefits of exception-based error handing
1. Separation of concerns
open ( f i l e ) ;
i f ( opened )
{
parse ( stream ) ;
i f ( parsed )
{
i n t e r p r e t ( con t e n ts ) ;
i f ( i n t e r p r e t e d )
ac t ( ) ;
else
ret urn in t e r p r e t a t i o n _ e r r o r ;
}
else
ret urn pa r s e _e rr or ;
}
else
ret urn o pen_ e rro r ;
t ry
{
open ( f i l e ) ;
parse ( stream ) ;
i n t e r p r e t ( con t e n ts ) ;
}
catch
{
ope n _er r or : ha n d l e _ i t ( ) ;
pa r s e _e rr or : h an d l e _i t ( ) ;
i n t e r p r e t a t i o n _ e r r o r : ha n d l e _ i t ( ) ;
}
2. Up-stack propagation
3. (OO-like) Hierarchies
4. User-defined exceptions
3/20
The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
Drawbacks of the usual try/catch/throw model
1 Mandatory stack unwinding
Execution context is lost
2 2D Separation of Concerns
Throwing an exception
Handling it
Hardwired handler selection
4/20
The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
Table of contents
1 Basic Error Handling
Catching and throwing errors
Defining errors
2 Advanced Error Handling
Restarts
Dynamic error management
3 Beyond Error Handling
Example 1: warnings
Example 2: general signals
5/20
The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
Basic error handling
Equivalent to try/catch
( handlercase form ; ; t r y
( e r r or 1 ( var1 ) form1 ) ; ; catch
( e r r or 2 ( var2 ) form2 )
. . . )
Equivalent to finally
( unwindprotect form
cleanup ; ; f i n a l l y
. . . )
Non-local transfer to an exit point
tagbody/go
catch/throw
7/20
The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
User-defined errors
User-level definitions
( define condition name ( supers . . . )
( ( slotname op t i o n s . . . )
( slotname op ti o n s . . . )
. . . )
o p t i o n s . . . )
User-level throwing
( err or datum arguments . . . )
Jargon:
We don’t “throw an error”
We “signal a condition”
8/20
The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
3D Separation of Concerns
No mandatory stack unwinding
10/20
The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
User-defined restarts
Restart definition
( restart case form
( r e st a r t 1 ( args . . . ) o p t ion s . . . body )
( r e st a r t 2 ( args . . . ) o p t ion s . . . body )
. . . )
11/20
The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
Restarts management
Restart invocation
( invoke restart r e s t a r t args . . . )
Stack-preserving handlers
( handler bind
( ( e r ro r1 ha n d l e r f u n c tion ) ; ; you may c a l l
( e r r or 2 h a n d l e r f u n c t i o n ) ; ; i nv o k e r e st a rt
. . . ) ; ; here . . .
body )
12/20
The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
Dynamic error management
Restart definition
( restart case form
( r e s t a r t ( args . . . ) o p t ion s . . . body )
. . . )
Conditional availability
; ; The : t e s t o p t io n t o r e s t a r t s
( fin d r e star t r e s t a r t ) ; ; I s r e s t a r t av a i la bl e ?
( compute restarts ) ; ; Get a l l a va i l a b le r e s t a r t s
Interactive calling
; ; The : i n t e r a c t i v e o p t i on t o r e s t a r t s
( in vok e r e st a rt in t era cti vel y r e s t a r t )
13/20
The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
The truth about error
The function error:
1 signals a condition
2 looks for an appropriate handler
may handle the error (non-local exit)
may not (decline by returning)
3 eventually invokes the debugger
The function cerror:
“continuable error”
invokes the debugger but. . .
. . . establishes a restart named continue
What about not invoking the debugger at all ?
15/20
The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
Example 1: Warnings
The function warn:
1 signals a condition
2 looks for an appropriate handler
may handle the error (non-local exit)
may not (decline by returning)
3 eventually prints the condition and returns
Also establishes a muffle-warning restart
16/20
The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
The Truth about warn
The true truth about error
The function warn:
1 establishes a muffle-warning restart
2 calls signal to signal the condition
3 eventually prints the condition and returns
The function [c]error:
1 [establishes a continue restart]
2 calls signal to signal the condition
3 eventually invokes the debugger
The function signal:
1 looks for an appropriate handler
may handle the error (non-local exit)
may not (decline by returning)
2 simply returns otherwise
User-defined protocols on top of signal
17/20
The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
Example 2: coroutines (sort of) and yield
Generators / iterators, really
Coroutines:
“yield” values
retain their
state
position
Generator example
( defun squares ( )
( loop : fo r i : from 0
: do ( y i e l d ( i i ) ) ) )
Retain state and position don’t unwind the stack
yield values signal them
The trick:
1 yield values by signalling a condition
2 use them in a condition handler (by side-effect)
3 let the handler return normally (pretend it declined) !!
18/20
The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
The big picture
Worth a thousand words
19/20
The bright
side of
exceptions
Didier Verna
Introduction
Basic Error
Handling
Catching and
throwing errors
Defining errors
Advanced
Error Handling
Restarts
Dynamic error
management
Beyond Error
Handling
Warnings
Signals
Conclusion
Conclusion
There is more to exceptions than meets the eye. . .
Traditional approach is limited
Stack unwinding
2D separation of concerns
Improvements
No (mandatory) stack unwinding
3D separation of concerns
Better error management
No restricted to errors
Not even restricted to exceptions
User-defined condition-based protocols
20/20