Re: Question about pattern matching and sealed types – redundant switch cases
Andreas Berheim Brudin
andreas.brudin at gmail.com
Sat Apr 19 17:26:08 UTC 2025
Thank you both for the quick replies.
I guess the fact that b1 and b2 is available outside of the if, hints at
some kind of flow-based type analysis (even though the new type is
implicitly declared in the pattern), but I would then have proven Brian's
point - that once that door is open, people will ask for more.
But given the semantics of Java, I understand that this doesn't fit very
well. The reason I ask was that we use a Result type (Ok/Err) quite a lot,
and the biggest complaint is the nestedness of the code, which often
becomes:
return switch(getSomething()) {
case Err(var e) -> yield someError(e);
case Ok(var something) -> {
yield switch (doThingWithSomething(something)) {
case Err(var e) -> yield someOtherError(e);
case Ok(var result) -> etc...
}
}
I guess you don't have any quick fixes for that other than resorting to
traditional exception handling.
Best,
Andreas
On Sat, Apr 19, 2025 at 7:08 PM Remi Forax <forax at univ-mlv.fr> wrote:
>
>
> ------------------------------
>
> *From: *"Andreas Berheim Brudin" <andreas.brudin at gmail.com>
> *To: *"amber-dev" <amber-dev at openjdk.org>
> *Sent: *Saturday, April 19, 2025 6:17:43 PM
> *Subject: *Question about pattern matching and sealed types – redundant
> switch cases
>
> Hi all,
>
> I'm new to the list—apologies if this has been discussed before, and
> thanks in advance for your time.
>
> I have a question about pattern matching with sealed types. Consider this
> example:
>
> sealed interface A permits B, C {}
> record B(String b1, String b2) implements A {}
> record C(String c) implements A {}
>
> A myVar = ...;
> if (!(myVar instanceof B(var b1, var b2))) {
> return switch (myVar) {
> case C(var c) -> c;
> case B b -> throw new IllegalStateException("should not happen");
> };
> }
> // use b1, b2
>
> Here, I want to keep an early-return style, but since I need to return a
> value from C, I have to use a switch. This leads to redundancy: we've
> already tested myVar is not a B, so that case should be statically
> unreachable.
>
> My questions:
>
> 1. Is there any consideration or ongoing work to allow the compiler to
> automatically eliminate such unreachable cases?
>
>
> The short answer is no :)
>
> Long answer,
> (1) myVar does not change its type, it is declared as an A, it always be
> an A (Groovy or Kotlin behave differently, they use flow typing)
> (2) the type system of Java has no notion of exclusion, the type A but
> not B does not exist
> (3) instanceof and switch does not have the same semantics, instanceof
> has no notion of exhaustiveness while a switch on a sealed type has.
>
> so because of (1) the type of myVar can not be changed, because of (2) its
> new type inside the if can not be "A but not B" and because of (3) the new
> type can not be only C.
>
>
>
> 2. If only one case remains (in this case, C), could it be possible to
> treat the variable as a C directly without requiring an explicit switch?
>
>
> No,
>
>
>
> Again, apologies if this has already been discussed. I'd appreciate any
> pointers to relevant threads or JEPs if so.
>
>
> The relevant JEPs are JEP 394 (for instanceof) and 441 (for switch).
>
>
>
> Thanks,
> Andreas
>
>
> regards,
> Rémi
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20250419/c02a0149/attachment.htm>
More information about the amber-dev
mailing list