[bitc-dev] RFI: BitC exceptions design

Jonathan S. Shapiro shap at eros-os.org
Thu Aug 11 11:44:31 EDT 2005


This is a Request For Input.


For several reasons, I have concluded that we need to declare
exceptions. Originally I though that we might get away without this, but
it now seems likely that we cannot.

However, this raises several questions:
  1. Should exceptions be able to carry state and/or other content?
  2. Is an exception a type or a value?
  3. Is an exception a reference type or a value type?
  4. Can exceptions sensibly be polymorphic?


Here are my provisional answers. If these seem wrong I would very much
like to know!

PROPOSED resolutions for (1,2,3):

If we are going to declare exceptions anyway, then the exception
declaration declares a reference type and the exception that is thrown
is an instance of that reference type.

Conceptually, I am assuming that the type Exception is an *open* tagged
union, and that each DEFEXCEPTION declaration declares a new union tag
and any accompanying fields. That is:

  (defexception oops string)

defines a new exception "oops" that includes as its parameter a single
string, which is thrown by:

  (throw (oops "I goofed"))

At the moment, I propose to model exceptions after the syntax of union
constructors, though I would personally prefer to have field names in
this situation. My sense is that unions should also have field names,
and if I can find a way to make that clean I plan to do it anyway, and
at that point exceptions will have named fields.

My opinion is that the Exception type should be a reference type. This
allows us to propagate an exception without knowing its parameters. The
only case I know of where this is a problem is "out of memory"
exceptions, and those can be handled by throwing a statically predefined
exception instance.

In order to throw **or catch** an exception, its declaration must be in
scope.


PROPOSED resolution for (4):

DEFEXCEPTION should NOT support parameterization, and in consequence an
exception is NOT a polymorphic type.

Rationale:

1. The receiving CATCH block is logically mutated by the THROW
operation. This triggers the value restriction, with the consequence
that any polymorphism would be restricted to a monomorphic resolution in
any case.

2. Pragmatically, there appears to be no way to figure out at the catch
site what the alpha type is. Consider a hypothetical declaration:

  (defexception (ListOops 'a) (list 'a))

That is, an exception that accepts a parameterized list as an argument.
It is very unlikely that the catch block will be able to know the
instantiation of 'a, and therefore nothing useful can be done with the
argument.

3. The exception to my comment in (2) appears to be try/catch/throw
sequences that are purely local. I don't think that this case is
compelling enough to justify inclusion in the language.

4. If exceptions are NOT polymorphic, then no monomorphism restriction
is induced on the catch block. I'm not sure yet, but this *may* mean
that it is possible to have exceptions that do not trigger a value
restriction.

So: Can anyone offer an example where polymorphic exceptions are
actually useful?


shap



More information about the bitc-dev mailing list