<div dir="ltr"><div>Thank you both for the quick replies.<br><br></div><div>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.</div><div><br></div><div>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:<br></div><div>return switch(getSomething()) {<br></div><div>  case Err(var e) -> yield someError(e);<br></div><div>  case Ok(var something) -> {<br></div><div>    yield switch (doThingWithSomething(something)) {<br></div><div>      case Err(var e) -> yield someOtherError(e);<br></div><div>      case Ok(var result) -> etc...</div><div>  }</div><div>}<br><br></div><div>I guess you don't have any quick fixes for that other than resorting to traditional exception handling.<br><br></div><div>Best,</div><div>Andreas</div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Sat, Apr 19, 2025 at 7:08 PM Remi Forax <<a href="mailto:forax@univ-mlv.fr">forax@univ-mlv.fr</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div style="font-family:arial,helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)"><div><br></div><div><br></div><hr id="m_-3354107300809954813zwchr"><div><blockquote style="border-left:2px solid rgb(16,16,255);margin-left:5px;padding-left:5px;color:rgb(0,0,0);font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt"><b>From: </b>"Andreas Berheim Brudin" <<a href="mailto:andreas.brudin@gmail.com" target="_blank">andreas.brudin@gmail.com</a>><br><b>To: </b>"amber-dev" <<a href="mailto:amber-dev@openjdk.org" target="_blank">amber-dev@openjdk.org</a>><br><b>Sent: </b>Saturday, April 19, 2025 6:17:43 PM<br><b>Subject: </b>Question about pattern matching and sealed types – redundant switch cases<br></blockquote></div><div><blockquote style="border-left:2px solid rgb(16,16,255);margin-left:5px;padding-left:5px;color:rgb(0,0,0);font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt"><div dir="ltr"><div>Hi all,<br><br>I'm new to the list—apologies if this has been discussed before, and thanks in advance for your time.<br><br>I have a question about pattern matching with sealed types. Consider this example:<br><br>sealed interface A permits B, C {}<br>record B(String b1, String b2) implements A {}<br>record C(String c) implements A {}<br><br>A myVar = ...;<br>if (!(myVar instanceof B(var b1, var b2))) {<br>    return switch (myVar) {<br>        case C(var c) -> c;<br>        case B b -> throw new IllegalStateException("should not happen");<br>    };<br>}<br>// use b1, b2<br><br>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.<br><br>My questions:<br><br>1. Is there any consideration or ongoing work to allow the compiler to automatically eliminate such unreachable cases?</div></div></blockquote><div><br></div><div>The short answer is no :)</div><div><br></div><div>Long answer,</div><div>  (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)</div><div>  (2) the type system of Java has no notion of exclusion, the type A but not B does not exist</div><div>  (3) instanceof and switch does not have the same semantics, instanceof has no notion of exhaustiveness while a switch on a sealed type has.</div><div><br></div><div>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. </div><div><br></div><blockquote style="border-left:2px solid rgb(16,16,255);margin-left:5px;padding-left:5px;color:rgb(0,0,0);font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt"><div dir="ltr"><div><br><br>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?</div></div></blockquote><div><br></div><div>No, <br></div><div><br></div><blockquote style="border-left:2px solid rgb(16,16,255);margin-left:5px;padding-left:5px;color:rgb(0,0,0);font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt"><div dir="ltr"><div><br><br>Again, apologies if this has already been discussed. I'd appreciate any pointers to relevant threads or JEPs if so.</div></div></blockquote><div><br></div><div>The relevant JEPs are JEP 394 (for instanceof) and 441 (for switch).</div><div><br></div><blockquote style="border-left:2px solid rgb(16,16,255);margin-left:5px;padding-left:5px;color:rgb(0,0,0);font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt"><div dir="ltr"><div><br><br>Thanks,<br></div>Andreas</div></blockquote><div><br></div><div>regards,</div><div>Rémi</div><div><br></div></div></div></div></blockquote></div>