[idea] introduce try/catch expressions (in addition to current try/catch statements)

Piotr Tarsa piotr.tarsa at gmail.com
Mon May 24 10:52:09 UTC 2021


Hi,

Recently I've come up with an idea (perhaps common one) to improve
Java's exception handling and it's summarized in the title i.e. it's
about introduction of try/catch expressions. I've searched mail
archives and found a thread about it already:
https://mail.openjdk.java.net/pipermail/amber-dev/2021-March/006972.html
I want to add some more perspective that could make try/catch
expressions more attractive.

One argument is that in contrary to
https://mail.openjdk.java.net/pipermail/amber-dev/2021-March/006973.html
> [quote start] To your point, yes, there are things that could be done to reduce the syntactic pain of checked exceptions.  But, as you point out, straightforward try-catch expressions don't remove most of the overhead; they just trim around the edges. [quote end]
the gain could be substantial if checked exceptions are dealt with
immediately instead of propagating them.

Let's say there are a few ways to fetch the same data, so I want to
start with the fastest way first and then try other ways. To avoid
nested identations I want to have a local variable that keeps the
result. In current Java I can have:

Optional<String> result = null;
try {
  result = Optional.of(readFileAsString(cachePath));
} catch (IOException e) {
  result = Optional.empty();
}

With try/catch expression it could be shortened - let's say that
insead of "try" there's "try ->" that turn try/catch from statement to
expression:

var result = try -> {
  Optional.of(readFileAsString(cachePath))
} catch (IOException e) {
  Optional.empty()
}

Here I gained not only more cleaner and compact code but also type
inference and effectively final variable for the result. Type
inference speeds up refactoring, while effectively final means that I
can use that variable from lambdas, nested classes etc

An IDE could detect such cases and display it in even shorter forms
(IntelliJ has code folding
https://confluence.jetbrains.com/pages/viewpage.action?pageId=51950197
) e.g.

var result = try -> { Optional.of(readFileAsString(cachePath)) } catch
(...) { Optional.empty() }

so the type of exception would be hidden by default. The final result
is a substantial improvement over the original form.



Second argument is that short syntax for try/catch expressions would
encourage people to represent failures as data (e.g. like in above
example, represent IO failures as Optional.empty()), instead of
wrapping them and propagating them (up the stack) blindly.  This could
be useful in situations like multithreaded and/or asynchronous
programming. Turning exceptions into domain classes means that (at
least for some time) the errors are now part of data flow, instead of
control flow (if I get these terms correctly here).  That helps when
passing a task into some library code. If I throw an exception (e.g.
wrapped in a RuntimeException) in some callback deep inside library
code then anything may happen (since I propagate upwards some unknown
stack) and I will wonder why  and where my data got lost or why
further data processing has stopped. If I turn an exception into some
object (e.g. Optional.empty()) then nothing will break in the
processing pipeline and I will have opportunity to deal with the
problem later in the same way as I  deal with successfully processed
data.


Third argument is that there are already switch expressions, added
decades after switch statements. Therefore introduction of try/catch
expressions could be thought of as something like introduction of
switch expressions - both are somewhat limited in scope (at  least at
first, without potential later additions). When put this way, this
could be more likely to be accepted without extending the scope of the
change (e.g. into a complete redesign of exceptions handling in
javac). To make things even more focused on turning  statements into
expressions, there could be a simultaneous sibling proposal to
introduce if/else expressions in addition to current if/else
statements.

Regards,
Piotr


More information about the amber-dev mailing list