argv_minus_one•

Scala does this, FWIW. In Scala, a return inside a lambda is translated into a throw and catch by the compiler. The exception class overrides fillInStackTrace, avoiding the overhead. Good stuff.

Scala also provides a trait (I think called NoStackTrace) that encapsulates this behavior, so you can conveniently make more flow-control exceptions yourself.

7
fripletister•

That's...awesome. I'm definitely excited for my online Scala course next month.

1
argv_minus_one•

That's not awesome. That's a minor convenience. Wait'll you see what's really awesome about Scala.

1
fripletister•

I'm aware of some of it. Everything I have seen, read and heard about Scala sounds appealing. Even small stuff like a provided trait for rolling your own cheap long jump via throwables gets me excited, though. :P

2
argv_minus_one•

It's a wonderful language. Flawed in some ways, but well worth the trouble.

1
Ferwerda•

So if the main cost is creating it, would it be (very) beneficial to build and have available some exceptions as static fields? From his description and use case, the stacktrace is not important here at all.

2
mschaefOP•

For me, the take away from the article is that 99% of the time, the conventional wisdom about Java exceptions is true. That is: they are a heavy-weight construct and should be exclusively used to report exceptional circumstances.

However... there's also a 1% case where what you really want to do is abort a deeply nested series of calls for a non-Exceptional reason. Consider a recursive-descent parser that detects a parse error in a deeply nested function. You may be 20 or 30 levels deep in the call stack when you encounter a parse error that essentially renders the entire parse invalid. Somehow, that deeply nested function needs to tell the top level of the parser that the parse is invalid (which probably also includes information on the nature of the error). There are at least two ways to do this:

  • Write explicit control flow that attempts to return all the way back to the top-level of the parser.
  • Throw a non-exceptional Exception that 1) tears down the stack that was allocated during the parse and 2) sends a meaningful object (the Throwable) back to the top level of the parser.

In cases like this, it's useful to think of Exceptions as control flow constructs. (But be sure to disable fillInStackTrace and give the Exception a name that indicates its unusual use case.)

3