<div dir="ltr">True, you may very well have a point here.<br><br><div>I actually have the "andThen" method on my Result, but I call it "flatMap" for consistency. Some people had a hard time understanding what was going on and I don't want to be the one pushing for every developer needing a degree in category theory so I am trying to introduce this safe programming style without requiring familiarity with too advanced functional concepts (even though many seem happy to flatMap their lists!).</div><div><br></div><div>But I guess just calling it "andThen" might alleviate some of the burden, thanks!</div><div><br></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:34 PM Brian Goetz <<a href="mailto:brian.goetz@oracle.com">brian.goetz@oracle.com</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"><u></u>

  
  <div>
    <font size="4" face="monospace">Right, you've built a monad here,
      and you want to express the happy path with a monadic do.  In
      Haskell you'd write this as: <br>
      <br>
          do<br>
              something <- getSomething()<br>
              result <- doThingWithSomething(something)<br>
      <br>
      and let the language desugar it accordingly.  But you can do this
      yourself in Java!  <br>
      <br>
          sealed interface Result<T> permits Ok, Err { <br>
              <U> Result<U> andThen(ThrowyFunction<T,
      U> f);<br>
              static<T> Result<T> of(ThrowySupplier<T>
      s) { ... }<br>
          }<br>
      <br>
      and then express your code as:<br>
      <br>
          Result.of(() -> getSomething())<br>
                .andThen(C::doThingWithSomething)<br>
                ...<br>
      <br>
      No nested code needed.<br>
          <br>
    </font><br>
    <div>On 4/19/2025 1:26 PM, Andreas Berheim
      Brudin wrote:<br>
    </div>
    <blockquote type="cite">
      
      <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">
        <div dir="ltr" class="gmail_attr">On Sat, Apr 19, 2025 at
          7:08 PM Remi Forax <<a href="mailto:forax@univ-mlv.fr" target="_blank">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_-362460745930723153m_-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>
    </blockquote>
    <br>
  </div>

</blockquote></div>