Fwd: switch-case-catch

Brian Goetz brian.goetz at oracle.com
Tue Jul 20 13:15:52 UTC 2021


The following idea was received on amber-spec-comments.

Essentially, the OP is asking that, if we're extending switch to cover 
more different kinds of cases, why not further extend it to treat an 
exception in evaluating the target as another kind of matchable result.  
It is a little like the current treatment of null, where, if there is a 
`null` case, it is treated as a switchable value, and if not, the switch 
completes abruptly with NPE.

While the questions are fair questions to ask, I see several challenges 
with this approach:

  - The motivations are mostly syntactic; `case X -> S` is more compact 
than `catch (E e) { S }`.  If these two had similar syntactic weight, it 
is less likely such suggestions would be made.

  - It only reduces the syntactic weight of try-catch in switches, but 
not other constructs.  This will surely be a "tomorrow's problems come 
from today's 'solutions'" thing.

  - People were uncomfortable about the "action at a distance" problem 
with other aspects of switch; this creates new ones (you have to scan 
all the cases to see which exceptions in evaluating the target are handled.)

  - The `catch` case labels are not being matched against the target of 
the switch, making the basic model for the body of a switch more 
complicated.

  - There are two possible interpretations of the approach; the 
desugaring suggested in the note seems the less sensible of the two to 
me.  They are:

    - The switch target is evaluated.  If evaluation completes normally, 
the non-catch cases are tried, otherwise the switch completes abruptly.  
If evaluation completes exceptionally, the catch cases are tried, and if 
none of those match, the switch completes abruptly.  In this version, 
only exceptions thrown by evaluation of the target can match.

    - The entire switch is considered to be wrapped by a big try-catch 
(this is what the OP suggests.)  This means exceptions thrown from the 
body of a previous case can also be caught by a later catch case.

If the motivation is to be more like a traditional Result<T,E>, the 
former interpretation makes more sense, because it more directly models 
switching over a Result<T,E>, with sugar to deconstruct the Result wrapper.


-------- Forwarded Message --------
Subject: 	switch-case-catch
Date: 	Tue, 20 Jul 2021 09:01:14 +0300
From: 	Omar Aloraini <aloraini.omar at gmail.com>
To: 	amber-spec-comments at openjdk.java.net



Hello,


With the introduction of sealed hierarchies and the enhancement of switch
expressions, I find myself wondering about the way I model errors.
Previously using a class `Result<T>` to model success or failure of an
operation was something that I used to do, but I quickly reverted as all my
code base methods returned the `Result` type, sometime I introduce another
type to model the error type such as Result<T,E>, where E is typically a
subtype of Exception. But again things get cumbersome, fortunately we now
have sealed hierarchies, which allows us to model multiple possible
outcomes of an operation, or a closed set of error conditions. Client code
is not ugly anymore as switch expressions and pattern matching amend it to
become more concise and pleasant to read and write, or as someone whom I
respected would say ‘less ceremony’. Now I find myself wondering why not
use Exceptions? For some method A that returns a value of type *T* or
throws an exception of two possible types, something like `T A() throws
E1,E2`, obviously you will lose that pleasant client code with switch and
pattern matching. But what if we had switch-case-catch where the catch
clauses must cover all exceptions in the throws clause for it to compile.

Something like the following:

Object r = switch (o.A()){

case T t -> ...

catch E1 e -> ...

catch E1 e -> ...

}

Semantically it would equivalent to:

Object r;

try {

r = switch (o.A()) {

case T t -> ...

} catch (E1 e) {

r = ...

} catch (E2 e) {

r = ...

}

}

You will also get the benefit of pattern matching for the catch clause,
something like `catch E1 | E2`.

I don't think it's necessary to use the `catch` keyword, `case` might just
work.

Apologies if this was suggested before.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20210720/c96ebba2/attachment-0001.htm>


More information about the amber-spec-experts mailing list