An exception handling system in which exceptions throwing does not unwind can do thing similar to generators or continuations, but without any of the implementation complexities and overhead. Plus the flexibilities of the exception type system: handlers found by subclass matching, and the potential for a handler to examine and decline exceptions so it can go on to match another handler.
In TXR, I simplified the concept by eliminating the duality of conditions and restarts. There are only exceptions. catch frames take an exception with unwinding. handle frames take an exception without unwinding (they can potentially decline it after looking at it). In the above example, keep-it? is an exception and so are yes, no and substitute.
So, why would you do the above instead of just, say:
You almost certainly wouldn't; it's just an illustration. There is a relationship between the two in that the mappend is an incomplete specification of a behavior which requires a function to be specified by the caller.
In the exception example, that is happening also: a function is required from the caller to complete the behavior. But that function isn't passed as a parameter; it is dynamically bound as a handler which is labeled by an exception symbol. The function doesn't simply return a value, but chooses from a menu of restart points.
That points to a whole different set of ways of organizing the code, and options for extending and maintaining it.
In TXR, I simplified the concept by eliminating the duality of conditions and restarts. There are only exceptions. catch frames take an exception with unwinding. handle frames take an exception without unwinding (they can potentially decline it after looking at it). In the above example, keep-it? is an exception and so are yes, no and substitute.
So, why would you do the above instead of just, say:
You almost certainly wouldn't; it's just an illustration. There is a relationship between the two in that the mappend is an incomplete specification of a behavior which requires a function to be specified by the caller.In the exception example, that is happening also: a function is required from the caller to complete the behavior. But that function isn't passed as a parameter; it is dynamically bound as a handler which is labeled by an exception symbol. The function doesn't simply return a value, but chooses from a menu of restart points.
That points to a whole different set of ways of organizing the code, and options for extending and maintaining it.