<html><body><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000"><div><br></div><div><br></div><hr id="zwchr" data-marker="__DIVIDER__"><div data-marker="__HEADERS__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><b>From: </b>"Brian Goetz" <brian.goetz@oracle.com><br><b>To: </b>"Remi Forax" <forax@univ-mlv.fr><br><b>Cc: </b>"John Rose" <john.r.rose@oracle.com>, "Alex Buckley" <alex.buckley@oracle.com>, "amber-spec-experts" <amber-spec-experts@openjdk.java.net><br><b>Sent: </b>Tuesday, November 15, 2022 12:35:24 AM<br><b>Subject: </b>Re: Late change to JEP 433<br></blockquote></div><div data-marker="__QUOTED_TEXT__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><font size="4"><font face="monospace">I win my bet! I had my money
on "If you send this, Remi will surely attempt to reopen his pet
NPE issue." We have been through this all before, so unless you
have something dramatically new and compelling, we're not
reopening this issue now. <br><br>
As a reminder, not all causes of MatchException come from
separate compilation anomalies. Some come from match remainder,
which is just an ordinary domain error, and separating the two
is only possible in the easy cases. <br><br>
I am not sure you fully understand how this works, otherwise you
wouldn't keep raising the same issue after getting the same
explanation. (For example, the "NPE can be thrown organically"
claim you make here, which you've made before, is wrong; it is
possible a later pattern can match Box(null), and we do not
throw ME until all choices are exhausted.) </font></font></blockquote><div><br></div><div>Let say we have,<br data-mce-bogus="1"></div><div> record Box(Box b) { }<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>and<br data-mce-bogus="1"></div><div> Box box = ...<br data-mce-bogus="1"></div><div> switch(box) {<br data-mce-bogus="1"></div><div> case Box(Box(var value)) -> ... // 1<br></div><div> case Box value2 -> ... // 2<br data-mce-bogus="1"></div><div> }<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>you can translate it line by line that way,<br data-mce-bogus="1"></div><div> if (box == null) {<br data-mce-bogus="1"></div><div> throw new NPE();<br data-mce-bogus="1"></div><div> }<br data-mce-bogus="1"></div><div> if (box instanceof Box $b1) {<br data-mce-bogus="1"></div><div> Box $b2 = $b1.b;<br data-mce-bogus="1"></div><div> if ($b2 instanceof Box value) {<br data-mce-bogus="1"></div><div> ... // 1<br data-mce-bogus="1"></div><div> }<br data-mce-bogus="1"></div><div> }<br data-mce-bogus="1"></div><div><div> if (box instanceof Box value2) {</div><div> ... // 2</div><div> }</div></div><div> throw new MatchException(...)<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>but</div><div> - the first null check is not really needed if later you ask for the content of the box,<br data-mce-bogus="1"></div><div> - the instanceofs "box instanceof Box $b1" and "box instanceof Box value2" are useless and you do not need to do that check twice<br data-mce-bogus="1"></div><div> </div><div><div>a better code is<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div> Box $b2 = box.b; // will throw a NPE<br></div><div> if ($b2 == null) {</div><div> ... // 2<br data-mce-bogus="1"></div><div> }<br data-mce-bogus="1"></div><div> Box value2 = $b2;<br data-mce-bogus="1"></div><div> ... // 1 <br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>You can observe that like the switch on strings or the switch on enums, the NPE comes "organically" from asking the content of the box.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>The "throw new MatchException" disappears because there is no need for a catch all anymore, this is also true if the last instanceof on a subtype of a sealed type is transformed to a cast instead of an instanceof.<br data-mce-bogus="1"></div><div> <br data-mce-bogus="1"></div>But generating such code requires to merge subsequent patterns like Jan has tried to do in a recent patch, something i believe we will have to do anyway because the current perf is not that great.<br></div><div><br data-mce-bogus="1"></div><div>Rémi<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><font size="4"><font face="monospace"><br><br><br><br><br></font></font><br>
<div class="moz-cite-prefix">On 11/14/2022 6:23 PM,
<a class="moz-txt-link-abbreviated" href="mailto:forax@univ-mlv.fr" target="_blank">forax@univ-mlv.fr</a> wrote:<br>
</div>
<blockquote cite="mid:1523992166.45467714.1668468233208.JavaMail.zimbra@u-pem.fr">
<div style="font-family: arial, helvetica, sans-serif; font-size:
12pt; color: #000000">
<div><br>
</div>
<div><br>
</div>
<hr id="zwchr">
<div>
<blockquote style="border-left:2px solid
#1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><b>From:
</b>"Brian Goetz" <a class="moz-txt-link-rfc2396E" href="mailto:brian.goetz@oracle.com" target="_blank"><brian.goetz@oracle.com></a><br>
<b>To: </b>"Remi Forax" <a class="moz-txt-link-rfc2396E" href="mailto:forax@univ-mlv.fr" target="_blank"><forax@univ-mlv.fr></a>, "John
Rose" <a class="moz-txt-link-rfc2396E" href="mailto:john.r.rose@oracle.com" target="_blank"><john.r.rose@oracle.com></a><br>
<b>Cc: </b>"Alex Buckley" <a class="moz-txt-link-rfc2396E" href="mailto:alex.buckley@oracle.com" target="_blank"><alex.buckley@oracle.com></a>,
"amber-spec-experts"
<a class="moz-txt-link-rfc2396E" href="mailto:amber-spec-experts@openjdk.java.net" target="_blank"><amber-spec-experts@openjdk.java.net></a><br>
<b>Sent: </b>Monday, November 14, 2022 11:40:27 PM<br>
<b>Subject: </b>Re: Late change to JEP 433<br>
</blockquote>
</div>
<div>
<blockquote style="border-left:2px solid
#1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><font size="4"><font face="monospace">Its MatchException. Error
would not be appropriate, since this is the same
exception that gets used for remainder (e.g.,
Box(Box(var x)) against a target of Box(null)).</font></font></blockquote>
<div><br>
</div>
<div>I still think we should throw a NPE when a destructuring
something which is null.<br>
</div>
<div><br>
</div>
<div>It will make the semantics of MatchException very similar
to LambdaConversionException, i.e. a lot of users will never
see it because it can be thrown only when there is a
separate compilation issue or a bug in the deconstructor.</div>
<div><br>
</div>
<div>If you take a look to the implementation, the NPEs can be
thrown organically as the result of calling the
deconstructor (or the accessor methods) on null, instead of
adding a nullcheck that goto to the location where the
MatchException is thrown.<br>
</div>
<div><br>
</div>
<div>Rémi<br>
</div>
<div><br>
</div>
<blockquote style="border-left:2px solid
#1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><br>
<br>
<div class="moz-cite-prefix">On 11/14/2022 5:31 PM, Remi
Forax wrote:<br>
</div>
<blockquote cite="mid:842334026.45461578.1668465117769.JavaMail.zimbra@u-pem.fr">
<pre class="moz-quote-pre">I'm confused, is it MatchError or MatchException ?
Because if it's an error instead of an exception, it may be less an issue in term of backward compatibility but it is not what is proposed, right ?
Rémi
----- Original Message -----
</pre>
<blockquote>
<pre class="moz-quote-pre">From: "John Rose" <a class="moz-txt-link-rfc2396E" href="mailto:john.r.rose@oracle.com" target="_blank"><john.r.rose@oracle.com></a>
To: "Alex Buckley" <a class="moz-txt-link-rfc2396E" href="mailto:alex.buckley@oracle.com" target="_blank"><alex.buckley@oracle.com></a>
Cc: "amber-spec-experts" <a class="moz-txt-link-rfc2396E" href="mailto:amber-spec-experts@openjdk.java.net" target="_blank"><amber-spec-experts@openjdk.java.net></a>
Sent: Monday, November 14, 2022 8:24:04 PM
Subject: Re: Late change to JEP 433
</pre>
</blockquote>
<blockquote>
<pre class="moz-quote-pre">On 14 Nov 2022, at 10:56, Alex Buckley wrote:
</pre>
<blockquote>
<pre class="moz-quote-pre">… ICCE can hand over to MatchException …
</pre>
</blockquote>
<pre class="moz-quote-pre">Precisely; I agree that it is time for this to happen. Thanks, Alex for
reminding us of the history and lineage of ICCE, and why it doesn’t make sense
for switch statements (not even classic switch-over-enum).
As a program linkage error, ICCE is necessarily uncommunicative when applied to
a misconfigured switch statement. Using a MatchError is on the other hand
highly informative: The user (and possibly try/catch logic surrounding the
failure) knows exactly what happened, that a set of matches expected to succeed
has failed.
So, here’s a possible knock-on advantage if we hand off from ICCE to ME: If
there is further development of the concept of “a set of matches which is
required to succeed”, the error processing can continue to be unified under the
ME. Brian’s ideas about “let-statements” entail a single pattern which is
required to match; ME is surely the right way to signal failure (if not
something more specific like CCE or NPE, which is an interesting
side-conversation). Or, if we ever did Haskell-style method overloads that
discriminate arguments by means of patterns, surely they would desugar to
omnibus methods that start with switches; once again ME surely makes sense as a
way to signal inapplicability of such match-based methods.
— John
P.S. More speculatively, and probably a bridge too far, would be to employ
MatchException as a part of a meta-language protocol that defines how sets of
patterns compose, and in particular how one part of a composite signals failure
to the whole composite. (Surely there is some future use for X in methods :
method handles :: patterns : X; that’s what I mean by a meta-language
protocol.) I say this is a bridge too far because Java exceptions are not a
very good tool for normally-frequent control flow, and also because ME, like
NPE or CCE, probably best signals a failure of the programmer’s settled
intentions about some code, rather than signaling an alternative control path
(like if/else). Still, I wanted to point this out because in other languages
exception-like concepts are used to convey backtracking out of composite
control flow patterns, and if we decided to try this out for Java,
MatchExpression would raise its hand and say “pick me!”
</pre>
</blockquote>
</blockquote>
<br>
<br>
</blockquote>
</div>
</div>
</blockquote>
<br><br></blockquote></div></div></body></html>