Implicit switch exceptions (was: [switch] Status of implementation of switch expression)
Brian Goetz
brian.goetz at oracle.com
Tue Feb 27 22:33:18 UTC 2018
On 2/27/2018 5:23 PM, John Rose wrote:
> On Feb 27, 2018, at 1:30 PM, Brian Goetz <brian.goetz at oracle.com
> <mailto:brian.goetz at oracle.com>> wrote:
>>
>> (Some have questioned whether inserting the throwing default
>> automatically is wise, but I like the fact that it amounts to an
>> assertion that "these are all the enum constants in type E", and
>> getting an exception when that assumption is seen to be violated.)
>
> +100 the exception is the right response to an event at runtime that
> was not supposed to happen at compile time.
THe alternative is the status quo; make the user declare a default (that
presumably throws an AssertionError, and probably with a less
informative message than the compiler would provide, because the user is
already annoyed they have to write this code.)
> (I assume the user
> *must* mention all the enums present statically at compile time,
> right?)
Right. An expression switch must be exhaustive; switching over all the
known constants of an enum is considered exhaustive. Any switch with a
default is considered exhaustive. We have more fun in store for us to
reason about other forms of exhaustiveness as our patterns get more
interesting.
> Meanwhile, if there is a dynamic data-dependent condition
> which is thought to be unlikely but must be reported with an
> exception, we often use a RuntimeException, such as NPE,
> CCE, ASE, IAE. Note that EnumConstantNotPresentException,
> is thrown by annotation processing.
Heh, didn't know about ECNPE; might well be good enough to reuse for
now. Certainly clear enough; you had a switch without a default where
the desired Enum Constant is Not Present in your switch, which is an
Exception. But as you point out later, there will be other forms of
switches that looked exhaustive at compile time (switching over all
types in a sum type) and are not at runtime (someone added one).
Whether we want the same exception in both cases, or a situationally
specific one like ECNPE, is open to discussion.
I too prefer an RE to an Error.
> If we could prove that all such incomplete switches are
> the results of sihfts to API hierarchies after static compilation,
> that would be an argument in favor of ICCE.
The problem with ICCE is that adding an enum constant is *not*
incompatible (the way removing one is); it's just that the code embodies
an assumption which this change breaks. So ICCE feels too strong, and
too low-level, here.
> Bottom line: unless we can tie switch coverage errors closely
> to API structure, I think we need a new RE named, roughly,
> SwitchDefaultNotFoundException.
>
Scala uses MatchError (extends RuntimeException) for this.
More information about the amber-dev
mailing list