Hacker News new | ask | show | jobs
by lukasLansky 3962 days ago
Strong type system with a good support of checked exceptions would tell you what kind of exceptions can arise from every function call. If you don't check them in your function code, they would add to the list of exceptions that your function can throw. It would basically turn every function you write with return type T into Either<T, ExceptionA, ExceptionC, ExceptionH> with syntax sugar that would transfer exceptions between calls so you don't have to spend your time with constant transfering of error properties of your return objects.

This would allow you to check stuff on places you desire (sometimes right after function, sometimes in the UI thread) and have tooling support for managing what is left unchecked.

Let's build something like that for C# using Roslyn! Issues of Java-style checked exceptions can be overcome using proper typing with generics.

2 comments

In layered code, if not recoverable by the current layer, you should always encapsulate checked exceptions thrown by a lower layer - translated into an exception of the current layer (maybe generalized). This simple rule is often declared as overhead. I don't get that. I like code to be precise. The only situations where this gets complicated are those, where the rule is violated. And I think, the rejection of checked exceptions is often based on experiences with bad API design.

Exception handling must be trained and educated. There is no silver bullet.

With this scheme you would end up with pretty bad problems regarding function pointers and lambdas. Because the type is deeply implicit, you would have two function pointers that look compatible but are totally incompatible. Then when you want to assign them to a variable -- how do you know a priori what type to declare the variable?
This would seem to be "just" a matter of correctly handling polymorphism along yet another axis.

Let's say we had the following C++ code:

    int foo(int (*bar)(char), int (*baz)(), char c) {
        try {
            return bar(c)
        } catch(SomeException &e) {
            raise otherexception;
        }
    }
What exceptions can be raised by foo?

The answer is simply computed - "anything raised by its first argument except SomeException, plus the type of otherexception".

Such a system would be tremendously more flexible than Java's checked exceptions, while still allowing you to confidently restrict what might be thrown in a section of code.

Good question. :-) I guess there definitely would be cases where the programmer would be restricted in what they want to do -- this is a nature of type systems. For example, I guess following code would not compile:

var f = (n) => n / 5; f = (n) => 5 / n;

What I hope for is that usual patterns would survive in a convenient manner. For example, calling function with function argument that is evaluated inside this function is something that could be handled by language without too many problems.