views:

103

answers:

6

I'm well aware of the whole argument over whether or not checked exceptions are a good idea and I fall on the side that they are...but that is not the point of this question. I'm in the process of designing a fairly simple compiled OOP language and I've decided to use checked exceptions basically as a way of returning errors without going down the C route of returning error codes.

I'm looking for some insight as to how I could improve on the Java model of checked exceptions to eliminate most of their bad aspects, perhaps a syntactic change or changing the actual functionality slightly. One of the main criticisms against checked exceptions is that lazy programmers are likely to swallow them and so errors would not appear.

Perhaps it could be optional to catch exceptions and therefore if one is not caught the program would crash? Or maybe there could be specific notation to denote that an exception is not being handled (like the C++ virtual function '= 0' notation)? Or I could even cause the program to crash if the exception handler is empty (though this might surprise programmers new to the language)?

How about the try...catch syntax, do you think there could be a more concise way of expressing that an exception is being caught? The language will use a garbage collector, much like Java, so is there any need for the finally clause? Finally, what other disadvantages are there to checked exceptions and what potential solutions (if any) exist?

A: 

I don't see another way to bound a block of code possible of errors. I think that the try .. catch block is consistent. Ruby, as a improvement, has a keyword that allows to repeat the block of code that was fail, it's a good improvement, i think

Lucas
+1  A: 

I think you should read Neil Gafters post regarding the improved exception handling in jdk7 and an interview with Anders Hjelsberg about exception handling in C# (vs. Java)

Steen
+1  A: 

I think you should consider using a tri-state monad like Lift's Box type to handle Errors. Then you won't need to use Exceptions at all.

http://github.com/dpp/liftweb/blob/master/framework/lift-base/lift-common/src/main/scala/net/liftweb/common/Box.scala

Viktor Klang
+1  A: 

I'm well aware of the whole argument over whether or not checked exceptions are a good idea and I fall on the side that they are...

FWIW, I agree -- by and large, they're a Good Thing(tm). The bad habits of programmers around the use of a feature do not necessarily mean a feature is bad. In most cases, I think programmers don't understand that they can take a pass on the exception and buck it up the chain.

Perhaps it could be optional to catch exceptions and therefore if one is not caught the program would crash?

Java has that feature (RuntimeException and its subclasses are unchecked exceptions).

Or maybe there could be specific notation to denote that an exception is not being handled...

Java has that; the throws clause in the method declaration.

How about the try...catch syntax, do you think there could be a more concise way of expressing that an exception is being caught?

Granted it can feel a bit clunky, but the goal is to factor exceptional conditions out of the mainline logic.

However, I do have a couple of suggestions for try..catch:

catch..from

This is something I've wanted in Java and related languages for a long time (really need to write this up properly and submit a JSR): catch...from.

Here's an example:

FileOutputStream    output;
Socket              socket;
InputStream         input;
byte[]              buffer;
int                 count;

// Not shown: Opening the input and output, allocating the buffer,
// getting the socket's input stream

try
{
    while (/* ... */)
    {
        count = input.read(buffer, 0, buffer.length);
        output.write(buffer, 0, count);

        // ...
    }
}
catch (IOException ioe from input)
{
    // Handle the error reading the socket
}
catch (IOException ioe from output)
{
    // Handle the error writing to the file
}

As you can see, the goal here is to separate the unrelated error handling for socket read errors and file write errors. Very basic idea, but there are a lot of subtleties involved. For instance, exceptions thrown by other objects being used under-the-covers by the socket or file output stream instance need to be handled as though thrown by that instance (not that hard, just need to be sure instance information is in the stack trace).

This is something one can do with existing mechanisms and strict coding guidelines, but it's very difficult.

Multiple catch expressions in a single block

A'la the planned JDK7 enhancements.

Retry

Very, very much harder to provide than the above and also much easier for people to work around, so the value's a lot lower. But: Provide a "retry" semantic:

try
{
    // ...stuff here...

    if (condition)
    {
        foo.doSomething();
    }

    // ...stuff here...
}
catch (SomeException se)
{
    if (foo.takeRemedialAction() == Remedy.SUCCESS)
    {
        retry;
    }

    // ...handle exception normally...
}

Here, doSomething can fail in an exceptional way, but in a way that takeRemedialAction may be able to correct. This continues the theme of keeping the exceptional conditions out of the main line of logic. Naturally, retry takes execution back to the operation that failed, which may be deep in doSomething or some submethod it's called. You see what I mean about challenging.

This one is much easier for teams to do with existing mechanisms: Just make subroutine that's doSomething plus takeRemedialAction on exception, and put that call in the main line logic instead. So, this one's low on the list, but hey...

T.J. Crowder
10+ years on, I've *finally* gotten around to at least doing a blog post on `catch..from`: http://blog.niftysnippets.org/2010/02/catchfrom.html Maybe I'll get to doing a JSR this year.
T.J. Crowder
The problem with your retry thing is that there is no way to know where to retry from. The JVM instruction that failed? The processor instruction? The statement in which the method is caught (which is the only reasonable way)? Some random point up the call stack? Continuable exceptions are actually in use, but only in low-level code and very specific circumstances. For example, a page fault will trigger an exception handler, which then swaps in the page and retries the same processor instruction that failed.
erikkallen
@erikkallen: All very valid points, the bounds and behavior would have to be *very* clearly defined. I will point out that this is not a new thing, and it is implemented in some very high-level languages -- VB6, for instance (may it rest in peace -- **soon**) had `Resume` and the horror that was `Resume Next`. And most people got by perfectly well not actually knowing the details of how it worked. For any modern implementation going forward, I'd want the details. :-) (Writing that, I'm seeing a major distinction between my `retry` and VB6's `Resume`; but still, food for thought.)
T.J. Crowder
+3  A: 
Jörg W Mittag
A: 

The exception-handling mechanism of the programming language CLU is fully checked and is designed for rock-solid reliability. Since almost all modern exception mechanisms are more permissive versions of CLU's original model, it is well worth careful study. If you have access to a good library the paper by Liskov and Snyder is well worth reading.

Regarding syntax, there is a superb paper by Nick Benton and Andrew Kennedy that explains the weaknesses of standard syntax and proposes a compelling new variation. It should be required reading for anyone doing design in this area.

Norman Ramsey