# The Common Lisp Condition System ## 0. Preface ### 0.1 Abstract ### 0.2 What is a condition system? Introduction by Kent M. Pitman ### 0.3 Daydreaming ### 0.4 Preface ### 0.5 Hall of Fame ## 1 Basic concepts ### 1.1 Dynamic variables #### 1.1.1 Dynamic variables in C ##### 1.1.1.1 Implementing dynamic variables in C #### 1.1.2 Dynamic variables in Common Lisp #### 1.1.3 Alternatives in other languages ##### 1.1.3.1 Scheme ##### 1.1.3.2 Design patterns ### 1.2 Non-local transfers of control #### 1.2.1 `TAGBODY` and `GO` #### 1.2.2 `BLOCK` and `RETURN-FROM`/`RETURN` #### 1.2.3 `CATCH` and `THROW` ### 1.3 Lexical closures ## 2 Introducing the condition system ### 2.1 A simple system of hooks #### 2.1.1 Hook #1: launching Counter Strike ##### 2.1.1.1 Equivalent examples #### 2.1.2 Hook #2: only call Counter Strike players #### 2.1.3 Hook #3: only call parents... maybe #### 2.1.4 Hook #4: holiday wishes #### 2.1.5 Accumulating hooks #### 2.1.6 Hook #5: calling Tom's girlfriend again #### 2.1.7 Multiple types of hooks #### 2.1.8 Summary: the hook subsystem ### 2.2 A simple system of condition handlers #### 2.2.1 Exception handling ##### 2.2.1.1 First iteration: no handling ##### 2.2.1.2 Second iteration: signaling a condition ##### 2.2.1.3 Third iteration: entering the debugger #### 2.2.2 Protection against transfers of control #### 2.2.3 Clustering #### 2.2.4 Summary: the handler subsystem ### 2.3 A simple system of choices #### 2.3.1 Kate and Mark #### 2.3.2 Choice #1: escape ##### 2.3.2.1 The CHOICE structure ##### 2.3.2.2 Escaping through the front door ##### 2.3.2.3 Escaping through the back door ##### 2.3.2.4 Computing and invoking choices ##### 2.3.2.5 The results ##### 2.3.2.6 Same-named choices #### 2.3.3 Choice #2: excuses #### 2.3.4 Summary: the choice subsystem ### 2.4 A simple system of restarts #### 2.4.1 Interactive restarts ### 2.5 A simple system of actually-restarting restarts #### 2.5.1 Restarts that perform a non-local exit #### 2.5.2 From RESTART-BIND to RESTART-CASE #### 2.5.3 Simple restarts #### 2.5.4 Standard restarts and restart-invoking functions #### 2.5.5 Defining custom restart-invoking functions ### 2.6 Reporting conditions and restarts #### 2.6.1 Printing versus reporting #### 2.6.2 Custom condition reports #### 2.6.3 Custom restart reports ### 2.7 Warnings #### 2.7.1 Different ways of warning #### 2.7.2 Muffling warnings ### 2.8 Assertions #### 2.8.1 Simple assertions via ASSERT #### 2.8.2 Typechecking via CHECK-TYPE #### 2.8.3 Case assertions #### 2.8.3 Correctable case assertions #### 2.8.4 Arguments for continuable errors ### 2.9 A simple debugger #### 2.9.1 Reporting the condition in the debugger #### 2.9.2 Reporting the condition type in the debugger #### 2.9.3 Reporting the restarts in the debugger #### 2.9.4 Choosing the restarts in the debugger #### 2.9.5 Installing a custom debugger #### 2.9.6 Recursive debugger #### 2.9.7 Adding a REPL to the debugger #### 2.9.8 Backtraces #### 2.9.9 Associating conditions with restarts ## 3 Implementing the Common Lisp condition system ### 3.1 Package definition ### 3.2 Conditions #### 3.2.1 Base class for conditions #### 3.2.2 Defining new condition types ### 3.3 Coercing data to conditions ### 3.4 Restart basics #### 3.4.1 Restart class #### 3.4.2 Restart visibility and computing restarts #### 3.4.3 Invoking restarts ### 3.5 Binding restarts ### 3.6 Restart cases #### 3.6.1 First iteration: basics #### 3.6.2 Second iteration: forms instead of a function #### 3.6.3 Third iteration: managing the keyword differences #### 3.6.4 Fourth iteration: associating conditions with restarts #### 3.6.5 Implementing simple restarts ### 3.7 System-defined restarts ### 3.8 Assertions #### 3.8.1 Case failures #### 3.8.2 Case utilities #### 3.8.3 Non-correctable case assertions #### 3.8.4 Correctable case assertions #### 3.8.5 General assertions ### 3.9 Signaling ### 3.10 Handlers #### 3.10.1 Binding handlers #### 3.10.2 Handler cases #### 3.10.3 Testing assertions ### 3.11 A featureful debugger #### 3.11.1 Debugger commands #### 3.11.2 Evaluating Lisp forms #### 3.11.3 Reporting and returning conditions #### 3.11.4 Listing and invoking restarts #### 3.11.5 Debugger help and REPL ##### 3.11.5.1 REPL variables ##### 3.11.5.2 Debugger read-eval-print step #### 3.11.6 Debugger interface ### 3.12 Finishing touches #### 3.12.1 Integration #### 3.12.2 Additional work ## 4 Wrapping up ### 4.1 The purpose of the condition system ### 4.2 Binding versus casing ### 4.3 Separation of concerns ### 4.4 Algebraic effects ### 4.5 Downsides of the condition system #### 4.5.1 Separation from CLOS ##### 4.5.1.1 Making conditions of complex condition types #### 4.5.2 Dynamic extent of restart objects #### 4.5.3 Speed #### 4.5.4 Optimization settings #### 4.5.5 Introspection #### 4.5.6 Concrete condition types #### 4.5.7 Warning conditions and #'WARN #### 4.5.8 Implementing custom SIGNAL-like operators #### 4.5.9 Lack of functional interfaces to handlers and restarts #### 4.5.10 Smaller issues #### 4.5.11 Summary: downsides of the Common Lisp condition system ## 4.6 Condition system in practice ### 4.6.1 Unit test library: collecting results ### 4.6.2 Web framework: sending results over the network ### 4.6.3 GUI applications: interactive querying ### 4.6.4 Generating data: Python-like generators ## 5 Appendices ### 5.1 Appendix A: Implementation of dynamic variables in C ### 5.2 Appendix B: Additional utilities for working with Common Lisp conditions #### 5.2.1 CALL-WITH-HANDLER and CALL-WITH-RESTART #### 5.2.2 HANDLER-BIND\* and HANDLER-CASE\* #### 5.2.3 HANDLER-BIND-CASE ### 5.3 Appendix C: Lisp macros 101 #### 5.3.1 Basics of macro writing #### 5.3.2 Backquote #### 5.3.3 Symbol capture #### 5.3.4 Order of evaluation #### 5.3.5 Multiple evaluation #### 5.3.6 When not to write macros #### 5.3.7 Reference ### 5.4 Appendix D: condition system reference #### 5.4.1 Restarts and related functions ##### Class RESTART ##### Function RESTART-NAME ##### Function COMPUTE-RESTARTS ##### Function FIND-RESTART ##### Function INVOKE-RESTART ##### Function INVOKE-RESTART-INTERACTIVELY ##### Examples #### 5.4.2 Condition-restart association ##### Macro WITH-CONDITION-RESTARTS ##### Examples #### 5.4.3 Restart macros ##### Macro RESTART-BIND ##### Macro RESTART-CASE ##### Macro WITH-SIMPLE-RESTART ##### Examples #### 5.4.4 Standard restarts ##### Restart ABORT ##### Restart MUFFLE-WARNING ##### Restart CONTINUE ##### Restart STORE-VALUE ##### Restart USE-VALUE ##### Function ABORT, CONTINUE, MUFFLE-WARNING, USE-VALUE, STORE-VALUE ##### Examples #### 5.4.5 Defining and instantiating conditions ##### Macro DEFINE-CONDITION ##### Function MAKE-CONDITION ##### Examples #### 5.4.6 Assertions ##### Macro ASSERT ##### Macro CHECK-TYPE ##### Macro ECASE, ETYPECASE, CCASE, CTYPECASE ##### Examples #### 5.4.7 Condition signaling ##### Function SIGNAL ##### Function WARN ##### Function ERROR ##### Function CERROR ##### Examples #### 5.4.8 Handler macros ##### Macro HANDLER-BIND ##### Macro HANDLER-CASE ##### Macro IGNORE-ERRORS ##### Examples #### 5.4.9 Condition types ##### Condition Type CONDITION ##### Condition Type WARNING ##### Condition Type STYLE-WARNING ##### Condition Type SERIOUS-CONDITION ##### Condition Type ERROR ##### Condition Type SIMPLE-CONDITION ##### Condition Type SIMPLE-WARNING ##### Condition Type SIMPLE-ERROR ##### Condition Type STORAGE-CONDITION ##### Condition Type TYPE-ERROR ##### Condition Type SIMPLE-TYPE-ERROR ##### Condition Type CONTROL-ERROR ##### Condition Type PROGRAM-ERROR ##### Condition Type CELL-ERROR ##### Condition Type UNBOUND-VARIABLE ##### Condition Type UNDEFINED-FUNCTION ##### Condition Type UNBOUND-SLOT ##### Condition Type STREAM-ERROR ##### Condition Type END-OF-FILE ##### Condition Type PARSE-ERROR ##### Condition Type READER-ERROR ##### Condition Type PACKAGE-ERROR ##### Condition Type FILE-ERROR ##### Condition Type PRINT-NOT-READABLE ##### Condition Type ARITHMETIC-ERROR ##### Condition Type DIVISION-BY-ZERO ##### Condition Type FLOATING-POINT-INVALID-OPERATION ##### Condition Type FLOATING-POINT-INEXACT ##### Condition Type FLOATING-POINT-UNDERFLOW ##### Condition Type FLOATING-POINT-OVERFLOW ##### Examples #### 5.4.10 Debugger invocation ##### Variable \*BREAK-ON-SIGNALS\* ##### Variable \*DEBUGGER-HOOK\* ##### Function BREAK ##### Function INVOKE-DEBUGGER ##### Examples