<!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>