The above is more or less the way exceptions work in Smalltalk. (The elimination of "try" doesn't apply, because Smalltalk has no keywords.)
• Not all exceptions are resumable; there's Error is a subclass of exception that can't be resumed.
• Instead of conditions, Smalltalk allows a parameter to be supplied when resuming an exception, and this will be answered by the #signal message that originally raised the exception.
• Exception subclasses can implement #defaultAction, which is a used if there are no catch blocks to handle the exception. The default implementation opens a debugger.
The Wikipedia article on Lisp conditions (linked to by Someone) gives the example of an exception raised when the program attempts to open a file that doesn't exist. In Squeak (a dialect of Smalltalk) it would work like this, given the following bit of code:
1 [stream := FileDirectory default oldFileNamed: 'foo.txt']
2 on: FileDoesNotExistException
3 do: [:exception |
4 Transcript show: 'Could not open file: ', exception messageText.
5 exception pass].
• the message #on:do: is sent to the block on line 1
• #on:do: sets an exception handler and then evaluates the block on line 1
• somewhere in the implementation of #oldFileNamed: an exception is raised
• the runtime scans the stack and finds the exception handler we installed
• it creates a new stack frame to evaluate the handler block (lines 3-5) and passes in the exception as the argument
• line 4 creates a entry in the Transcript which is sort of a global log used for debugging
• line 5 reraises the exception
• the runtime continues looking up the stack, but doesn't find another exception hander
• the runtime sends #defaultAction to the exception object
• another frame gets added to the top of the stack to execute FileDoesNotException>>defaultAction
• the default action opens a dialog saying the file doesn't exist, and offers several options:
• (a) create the file
• (b) choose another filename
• (c) open a debugger
• if the user chooses (c), a debugger opens on the stack frame where the exception was raised
• if the user chooses (a), the file is created and opened
• if the user choosed (b), they get to type in the new filename, and we try to open that file, possibly raising a new exception
• if we successfully open the file via (b) or (c), the exception is resumed with the stream as argument
• the runtime unwinds the two stack frames it created
• the activation of #oldFileName: resumes and answers the stream
• the stream gets assigned to the stream variable, and execution continues, presumably to read the file