Fwd: switch-case-catch

Brian Goetz brian.goetz at oracle.com
Tue Jul 20 13:58:26 UTC 2021


After a few minutes more thought, this approach can be simulated pretty 
well by a library solution.

Suppose you wrote the following class (once):

     sealed class Result<T, E extends Exception> {
         record Succ<T, E extends Exception>(T t) extends Result<T,E> { }
         record Fail<T, E extends Exception>(E e) extends Result<T,E> { }

         interface ExceptionalSupplier<T, E extends Exception> {
             T get() throws E;
         }

         static<T, E extends Exception> Result<T,E> 
of(ExceptionalSupplier<T,E> s) {
             try {
                 return new Succ(s.get());
             }
             catch (Exception e) {
                 return new Fail(e);
             }
         }
     }

Note that no library needs to directly return Result; you can wrap an 
exceptional computation with Result.of(() -> expr).

Now, you can switch using ordinary pattern matching:

     switch (Result.of(() -> possiblyExceptionalExpression()) {

         case Succ(T t) -> ...
         case Fail(E e) -> ...
     }

And note that nested patterns work just fine here:

     switch (Result.of(() -> possiblyExceptionalExpression()) {

         case Succ(T t) -> ...
         case Fail(FooException e) -> ...
         case Fail(BarException e) -> ...
}

(Critics will say "but, that's more ceremony", because you have to wrap 
with a Result and then distinguish between Succ and Fail.  Supporters 
would say that this is a small price for saying what you mean.)


On 7/20/2021 9:15 AM, Brian Goetz wrote:
> 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/cb9a68a1/attachment.htm>


More information about the amber-spec-experts mailing list