Effect cases in switch
Brian Goetz
brian.goetz at oracle.com
Tue Dec 12 23:04:09 UTC 2023
>
> Exception cases can be used in all forms of `switch`: expression
> and statement
> switches, switches that use traditional (colon) or
> single-consequence (arrow)
> case labels. Exception cases can have guards like any other
> pattern case.
>
>
> I think I would prefer "case throws" to be spell "catch" even if we
> have to have a discussion about catch(Throwable t) vs catch Throwable t.
Ah, you've stepped in the trap. You know the rule: if you make a syntax
comment, you've implicitly signed up for all the semantics. Glad to know
you're on board :)
We knew that someone (everyone?) would ask about this, because its kind
of the obvious choice. But having thought about it for quite a while,
I'm firmly convinced that this is in the "obvious but wrong"
department. PLEASE, let's not have a back-and-forth on this, because I
don't want a substantive discussion to be derailed by a syntax
triviality (we can return to this topic after the substantitive
discussions have played out), but I will summarize some of the reasons
why this is not what we want, because I think they are relevant to the
goals of the feature:
- The semantics would be extremely confusing, because a `case throws`
matches only exceptions thrown _in evaluating the selector_, just like
other cases match the result of a successful evaluation of the
selector. But if we expressed this as `switch ... catch`, users would
forever be assuming, incorrectly, that they mean to be catching all
errors from the switch block, including both those from the selector and
those from the body. That is *not* what this construct is about.
- The *whole point* of this feature is allowing evaluation failures to
be handled consistently and uniformly with successful evaluation.
Having a different syntax for handling failures does not help and does
not highlight the uniformity. Again, that is not what this constructs
is about.
The keyword `catch` is familiar but that is a very short-lived benefit.
The purpose of the feature is to allow uniform handling of results and
effects; the syntax should reflect that.
>
>
>
> Exception cases have the obvious dominance order with other
> exception cases (the
> same one used to validate order of `catch` clauses in
> `try-catch`), and do not
> participate in dominance ordering with non-exceptional cases. It is a
> compile-time error if an exception case specifies an exception
> type that cannot
> be thrown by the selector expression, or a type that does not extend
> `Throwable`. For clarity, exception cases should probably come
> after all other
> non-exceptional cases.
>
> When evaluating a `switch` statement or expression, the selector
> expression is
> evaluated. If evaluation of the selector expression throws an
> exception, and
> one of the exception cases in the `switch` matches the exception,
> then control
> is transferred to the first exception case matching the
> exception. If no
> exception case matches the exception, then the switch completes
> abruptly with
> that same exception.
>
>
> I don't want to be the guy implementing this :)
Good news, Jan has volunteered to be that guy :)
> I understand the appeal of such construct, it's a way to switch (eheh)
> from a world with exceptions to a more functional world where errors
> are values.
>
And even more so, to allow existing effectful APIs (like Future::get) to
be consumed as uniformly as they are implemented.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-observers/attachments/20231212/15676ae0/attachment-0001.htm>
More information about the amber-spec-observers
mailing list