Skip to content

zz note: exception improvements

David Jeske edited this page May 27, 2017 · 8 revisions

Basic Improvements:

The current exception implement is just the beginning of what is useful in an exception system. Small improvements that would help include:

  • finally or Swift-style defer
  • pattern match with multiple matches leading to a single handle expression a | b | c -> action

A major shortcoming is that by using polymorphic variants as exception types, which lack subtyping, there is no way to catch a "common" exception type to get common information about any exception thrown.

  • some form of common exception base (record?), with:
    • string description
    • source (file/line/function/module)
    • child (for chained exceptions)
    • ability to get a stack-backtrace
      • can this be done lazily with continuations?

Exceptions, Threading, and Co-routines

The current exception stack is managed in a global variable, called *the-exception-handler*. This presents a problem when there are multiple hardware threads or co-routines.

One solution is to store the exception chain in hardware-thread-local-storage, and have coroutine threading code explicitly swap it out with the current co-routine.

Another solution is to provide some form of continuation-walking (like stack-walking), and register the exception handlers with the continuation frames themselves. When an exception is thrown, it would walk through continuation frames looking for exception handlers, much like it's done in other languages.

Exception Inference, row polymorphic parametric exceptions

Having exceptions undeclared makes an incredibly painful surface area of potential problems. However, Java-style checked exceptions create two substantial problems:

  • Java code is polluted with exception declarations
  • Java's static checked-exception declarations can not account for lambdas

We'd like to investigate a possible solution to these problems using exception inference and row-polymorphic parametrics

  • exceptions throw would be inferred and made an automatic part of the type signature of functions. For functions within a program, this would behave somewhat like un-checked exceptions, as they would never need to be declared. However, because they are inferred, IDE tools could show exceptions emerging from any particular call. An optional compiler flag would decide whether exceptions reaching the root of a program uncaught were warnings or errors.
  • At public module boundaries (should they ever exist, as Irken is currently a whole-program compiler only), thrown exceptions would be declared as part of the public type signature of the module. However, functions which accept and use lambdas would be parametric in the type of those lambda exception types. In the case that a lambda throws an exception, then that new exception will be inferred to be thrown as part of the parametric exception specification.

Condition Handlers

Scheme/LISP is noteworthy for having a unique type of error handling system called condition handlers, using signal-condition. This system does not immediately unroll the stack like try/catch, but instead allows the registration of a condition handler which runs below the stack of the error, offering the possibility of correct-and-resume. In a way, it's like a registration of generic lambda handlers for named error conditions.

Is there a place for this type of condition handling? Is it practical to make them statically typed?