<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <font size="4" face="monospace">Yes, `flatMap` would be the
      traditional name.  I used `andThen` because `flatMap` scares a lot
      of Java developers.  And it's fine for you to do the same!  I
      think you would agree that it's better to get your team writing
      the simpler, more readable code, than being scared off by the
      "correct" terminology.  Some day they will realize that they've
      been flatMapping for years, and it's not as scary as they
      thought.  <br>
      <br>
      If I were designing this API I would also want to do a
      requirements analysis on error handling modes.  In your original
      example, you didn't just throw whatever error the Err wrapped; you
      wrapped that error with some other error, that presumably adds
      some context to the error, like what you were trying to do at the
      time.  And that can be pretty valuable for diagnosing the app when
      things go wrong.  So you may want to provide some support for
      mapping errors as well, to widen the happy path that you want to
      keep developers on.  <br>
      <br>
      <br>
    </font><br>
    <div class="moz-cite-prefix">On 4/19/2025 1:42 PM, Andreas Berheim
      Brudin wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CAKJ_Mj4-j9rCgcHFrxC9ZEpNDpQ4v18M93d-6B6Det2dhxuXQQ@mail.gmail.com">
      
      <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" moz-do-not-send="true" class="moz-txt-link-freetext">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">
          <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" moz-do-not-send="true" class="moz-txt-link-freetext">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" moz-do-not-send="true" class="moz-txt-link-freetext">andreas.brudin@gmail.com</a>><br>
                          <b>To: </b>"amber-dev" <<a href="mailto:amber-dev@openjdk.org" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">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>
    </blockquote>
    <br>
  </body>
</html>