Discover the functioning and example uses of the Common Lisp condition system. This book supplements already existing material for studying Common Lisp as a language by providing detailed information about the Lisp condition system and its control flow mechanisms; it also describes an example ANSI-conformant implementation of the condition system.
In part 1 of The Common Lisp Condition System, the author introduces the condition system using a bottom-up approach, constructing it piece by piece. He uses a storytelling approach to convey the foundation of the condition system, dynamically providing code to alter the behavior of an existing program. Later, in part 2, you’ll implement a full and complete ANSI-conformant condition system while examining and testing each piece of code that you write.
Throughout, the author demonstrates how to extend Lisp using Lisp itself by using the condition system as an example. This is done while paying proper attention to the CL restart subsystem, giving it attention on a par with the handler subsystem. After reading and using this book, you'll have learned about the inner functioning of the condition system, how to use it in your own Common Lisp coding and applications, and how to implement it from scratch, should such a need arise.
What You Will Learn
• Examine the condition system and see why it is important in Common Lisp
• Construct the condition system from scratch using foundational mechanisms provided by Common Lisp
• Program the condition system and its control flow mechanisms to achieve practical results
• Implement all parts of a condition system: conditions, restarts, handler- and restart-binding macros, signalling mechanisms, assertions, a debugger, and more
Who This Book Is For
Beginning and intermediate Lisp programmers, as well as intermediate programmers of other programming languages.
Author(s): Michał "phoe" Herda
Edition: 1
Publisher: Apress
Year: 2020
Language: English
Commentary: Vector PDF
Pages: 320
City: New York, NY
Tags: Lisp; Condition System; Programming
Table of Contents
About the Author
About the Technical Reviewers
Introduction
Preface
Chapter 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
Chapter 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 vs. 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 Type checking via CHECK-TYPE
2.8.3 Case assertions
2.8.4 Correctable case assertions
2.8.5 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
Chapter 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
Chapter 4: Wrapping up
4.1 The purpose of the condition system
4.2 Binding vs. 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
Chapter 5: Appendixes
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
5.4.1.1 Class RESTART
5.4.1.2 Function RESTART-NAME
5.4.1.3 Function COMPUTE-RESTARTS
5.4.1.4 Function FIND-RESTART
5.4.1.5 Function INVOKE-RESTART
5.4.1.6 Function INVOKE-RESTART-INTERACTIVELY
5.4.2 Condition-restart association
5.4.2.1 Macro WITH-CONDITION-RESTARTS
5.4.3 Restart macros
5.4.3.1 Macro RESTART-BIND
5.4.3.2 Macro RESTART-CASE
5.4.3.3 Macro WITH-SIMPLE-RESTART
5.4.4 Standard restarts
5.4.4.1 Restart ABORT
5.4.4.2 Restart MUFFLE-WARNING
5.4.4.3 Restart CONTINUE
5.4.4.4 Restart STORE-VALUE
5.4.4.5 Restart USE-VALUE
5.4.4.6 Function ABORT, CONTINUE, MUFFLE-WARNING, USE-VALUE, STORE-VALUE
5.4.5 Defining and instantiating conditions
5.4.5.1 Macro DEFINE-CONDITION
5.4.5.2 Function MAKE-CONDITION
5.4.6 Assertions
5.4.6.1 Macro ASSERT
5.4.6.2 Macro CHECK-TYPE
5.4.6.3 Macro ECASE, ETYPECASE, CCASE, CTYPECASE
5.4.7 Condition signaling
5.4.7.1 Function SIGNAL
5.4.7.2 Function WARN
5.4.7.3 Function ERROR
5.4.7.4 Function CERROR
5.4.8 Handler macros
5.4.8.1 Macro HANDLER-BIND
5.4.8.2 Macro HANDLER-CASE
5.4.8.3 Macro IGNORE-ERRORS
5.4.9 Condition types
5.4.9.1 Condition Type CONDITION
5.4.9.2 Condition Type WARNING
5.4.9.3 Condition Type STYLE-WARNING
5.4.9.4 Condition Type SERIOUS-CONDITION
5.4.9.5 Condition Type ERROR
5.4.9.6 Condition Type SIMPLE-CONDITION
5.4.9.7 Condition Type SIMPLE-WARNING
5.4.9.8 Condition Type SIMPLE-ERROR
5.4.9.9 Condition Type STORAGE-CONDITION
5.4.9.10 Condition Type TYPE-ERROR
5.4.9.11 Condition Type SIMPLE-TYPE-ERROR
5.4.9.12 Condition Type CONTROL-ERROR
5.4.9.13 Condition Type PROGRAM-ERROR
5.4.9.14 Condition Type CELL-ERROR
5.4.9.15 Condition Type UNBOUND-VARIABLE
5.4.9.16 Condition Type UNDEFINED-FUNCTION
5.4.9.17 Condition Type UNBOUND-SLOT
5.4.9.18 Condition Type STREAM-ERROR
5.4.9.19 Condition Type END-OF-FILE
5.4.9.20 Condition Type PARSE-ERROR
5.4.9.21 Condition Type READER-ERROR
5.4.9.22 Condition Type PACKAGE-ERROR
5.4.9.23 Condition Type FILE-ERROR
5.4.9.24 Condition Type PRINT-NOT-READABLE
5.4.9.25 Condition Type ARITHMETIC-ERROR
5.4.9.26 Condition Type DIVISION-BY-ZERO
5.4.9.27 Condition Type FLOATING-POINT-INVALID-OPERATION
5.4.9.28 Condition Type FLOATING-POINT-INEXACT
5.4.9.29 Condition Type FLOATING-POINT-UNDERFLOW
5.4.9.30 Condition Type FLOATING-POINT-OVERFLOW
5.4.10 Debugger invocation
5.4.10.1 Variable *BREAK-ON-SIGNALS*
5.4.10.2 Variable *DEBUGGER-HOOK*
5.4.10.3 Function BREAK
5.4.10.4 Function INVOKE-DEBUGGER
Index