Design of Exceptions and EHM in Cforall: Currently this is a combination of ideas and big questions that still have to be addressed. It also includes some other error handling options, how they interact and compare to exceptions. What is an Exception: In other words what do we throw? What is matched against, how does it carry data with it? A very important question that has not been answered. Option 1: Strutures Considering the current state of Cforall the most natural form of the exception would likely be a struture, implementing a trait repersenting the minimum features of an exception. This has many advantages, including arbitray fields, some polymorphism and it matches exceptations of many current systems. The main issue with this is matching, without OOP inheritance there is no exception hierarchy. Meaning all handling has to happen on the exact exception without the ease of grouping parents. There are several ways to attempt to recover this. The first is with conditional matching (a check after the type has been matched) which allows for matching particular values of a known type. However this does not dynamically expand and requires an extra step (as opposed to mearly allowing one). I would not recomend this as the primary method. Second is to try and use type casts/conversions to create an implicate hierachy, so that a catch clause catches anything of the given type or anything that converts to the given type. Plan9 (from what I know of it) would be a powerful tool here. Even with it, creating a hierarchy of types at runtime might be too expencive. Esecially since they are less likely to be tree like at that point. Option 2: Tags The other option is to introduce a new construct into the language. A tag repersents a type of exception, it is not a structure or variable (or even a normal type). It may be usable in some of those contexts. Tags can declare an existing tag as its parent. Tags can be caught by handlers that catch their parents. (There is a single base_exception that all other exceptions are children of eventually.) This allows for grouping of exceptions that repersent similar errors. Tags should also have some assotiated data, where and on what did the error occur. Keeping with the otherness of exception tags and allowing them to be expanded, using a parameter list. Each exception can have a list of paramters given to it on a throw. Each tag would have a declared list of parameters (which could be treated more like a set of fields as well). Child tags must use their parent's list as a prefix to their own, so that the parameters can be accessed when the child tag is matched against the parent. Option N: ... This list is not complete. Seperating Termination and Resumption: Differentating the types of exceptions based on exception would be hard with exceptions as structures. It is possible with exceptions as tags by having two base exceptions, one for each type of throw. However recompining them to dual types would be harder. Reguardless, using different keywords would also be useful for clarity, even if it does not add functality. Using the C++ like keywords would be a good base. Resumption exceptions could use a different set (ex. raise->handle) or use resume as a qualifier on the existing statements. Conditional Matching: A possible useful feature, it allows for arbitrary checks on a catch block instead of merely matching a type. However there are few use cases that cannot be avoided with proper use of a type hierarchy, and this shrinks even further with a good use of re-throws. Also it assumes one sweep, that might also be a problem. But might also give it an advantage over re-throws. Alternatives: Implicate Handlers & Return Unions Both act as a kind of local version of an exception. Implicate handlers act as resumption exceptions and return unions like termination exceptions. By local I mean they work well at one or two levels of calls, but do not cover N levels as cleanly. Implicate handles require a growing number of function pointers (which should not be used very often) to be passed to functions, creating and additional preformance cost. Return unions have to be checked and handled at every level, which has some preformance cost, but also can significantly clutter code. Proper tools can help with the latter. However, they may work better at that local level as they do not require stack walking or unwinding. In addition they are closer to regular control flow and are easier to staticly check. So even if they can't replace exceptions (directly) they may still be worth using together. For instance, consider the Python iterator interface. It uses a single function, __next__, to access the next value and to signal the end of the sequence. If a value is returned, it is the next value, if the StopIteration exception is thrown the sequence has finished. However almost every use of an iterator will add a try-except block around the call site (possibly through for or next) to catch and handle the exception immediately, ignoring the advantages of more distant exception handling. In this case it may be cleaner to use a Maybe for both cases (as in Rust) which gives similar results without having to jump to the exception handler. This will likely handle the error case more efficiently and the success case a bit less so. It also mixes the error and regular control flow, which can hurt readablity, but very little if the handling is simple, for instance providing a default value. Similarly, if the error (or alternate outcome) is common enough encoding it in the function signature may be good commuication. In short, these errors seem to be more effective when errors are likely and immediate. High failure operations, especially ones with failures that can be handled locally, might be better off using these instead of exceptions. Also the implicate handlers and return unions could use exceptions as well. For instance, a useful default might handler might be to throw an exception, seaching up the stack for a solution if one is not locally provided. Or here is a possible helper for unpacking a Result value: forall(otype T, otype E | exception(E)) T get_or_throw (Result(T, E) * this) { if (is_success(this)) { return get_success(this); } else { throw get_failure(this); } } So they can feed off of each other.