<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>"Swaranga Sarma" <sarma.swaranga@gmail.com>, "amber-dev" <amber-dev@openjdk.java.net><br><b>Sent: </b>Sunday, April 23, 2023 5:25:56 PM<br><b>Subject: </b>Re: Pattern matching on multiple objects<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">There was some brief mention
in an earlier document about this as a possible long-term future
feature.<br><br>
In functional languages, this comes mostly for free because the
selector expression (initial, move) is just a tuple, and "tuple
patterns" are just a trivial structural lifting of patterns.
Your state machine example is nice in that it exposes the
transition table directly in the language, but the real win here
is FizzBuzz :)<br><br>
String fizzBuzz(int i) { <br>
return switch (i % 5, i % 3) { <br>
case (0, 0) -> "FizzBuzz";<br>
case (0, _) -> "Fizz";<br>
case (_, 0) -> "Buzz";<br>
default -> String.valueOf(i);<br>
}<br><br>
In Java, this would be an extension to switch, where a selector
could be a sequence of values (like an argument list), and the
cases would be sequences of patterns. <br><br>
So the answer is maybe, someday.</font></font></blockquote><div><br></div><div>and a tuple be simulated by a local record, "_" can be simulated by a "var __" and a constant pattern can be simulated by a guard (the "when"),<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div> static String fizzBuzz(int i) {<br> record $(int d5, int d3) {}<br> return switch (new $(i % 5, i % 3)) {<br> case $(var d5, var d3) when d5 == 0 && d3 == 0 -> "FizzBuzz";<br> case $(var d5, var __) when d5 == 0 -> "Fizz";<br> case $(var __, var d3) when d3 == 0 -> "Buzz";<br> default -> "" + i;<br> };<br> }<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>regards,<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></font></font><br>
<div class="moz-cite-prefix">On 4/23/2023 7:19 AM, Swaranga Sarma
wrote:<br>
</div>
<blockquote cite="mid:CAGZD2TA+HDH=OMtW0xdREfaKHd=f5Z9UbA=11XstLsDuW==qPg@mail.gmail.com">
<div dir="ltr">
<div>I was recently writing a simple state machine where the
machine state has simple deterministic rules for the state
transitions given the current state and the input. I felt both
the state and the input types lent themselves well to sealed
classes and records but while implementing the logic I had to
resort to if-else statements. At that point, I felt if I were
able to switch and pattern-match on both the input types
together as a tuple, my logic would have been much clearer
while also concise.<br>
</div>
<div><br>
</div>
<div>Simplified sample code that I wish to be able to write
(although the point is not the exact syntax):</div>
<div style="background-color:rgb(30,31,34);color:rgb(188,190,196);font-family:"Consolas",monospace;font-size:9.8pt;white-space:pre"><span style="color:rgb(207,142,109)">sealed interface </span>State {}
<span style="color:rgb(207,142,109)">record </span>Start() <span style="color:rgb(207,142,109)">implements </span>State {}
<span style="color:rgb(207,142,109)">record </span>First() <span style="color:rgb(207,142,109)">implements </span>State {}
<span style="color:rgb(207,142,109)">record </span>Second() <span style="color:rgb(207,142,109)">implements </span>State {}
<span style="color:rgb(207,142,109)">record </span>End() <span style="color:rgb(207,142,109)">implements </span>State {}
<span style="color:rgb(207,142,109)">sealed interface </span>Move {}
<span style="color:rgb(207,142,109)">record </span>Jump(<span style="color:rgb(207,142,109)">int </span>steps) <span style="color:rgb(207,142,109)">implements </span>Move {
<span style="color:rgb(86,168,245)">Jump </span>{
<span style="color:rgb(207,142,109)">if </span>(steps < <span style="color:rgb(42,172,184)">0 </span>|| steps > <span style="color:rgb(42,172,184)">2</span>)
<span style="color:rgb(207,142,109)">throw new </span>IllegalArgumentException();
}
}
<span style="color:rgb(207,142,109)">record </span>None() <span style="color:rgb(207,142,109)">implements </span>Move {}
State <span style="color:rgb(86,168,245)">transition</span>(State initial, Move move) {
<span style="color:rgb(207,142,109)">return switch</span>(initial, move) {
<span style="color:rgb(207,142,109)">case </span>(Start, Jump(<span style="color:rgb(42,172,184)">1</span>)) -> First;
<span style="color:rgb(207,142,109)">case </span>(Start, Jump(<span style="color:rgb(42,172,184)">2</span>)) | (First, Jump(<span style="color:rgb(42,172,184)">1</span>)) -> Second;
<span style="color:rgb(207,142,109)">case </span>(First, Jump(<span style="color:rgb(42,172,184)">2</span>)) | (Second, Jump(_)) -> End;
<span style="color:rgb(207,142,109)">case </span>(End, _) -> End;
<span style="color:rgb(207,142,109)">case </span>(None, _) -> initial;
}
}</div>
<div><br>
</div>
<div>I did not see in the amber docs about being able to use
multiple patterns in a switch expression in any of the future
plans. It does not even have to be a switch really but
something to allow this type of expressivity. This feels very
much in line with the Data Oriented programming article
published a while ago.</div>
<div><br>
</div>
<div>Even if something like this were possible, I am guessing a
default clause would be needed in the switch because the
compiler cannot infer that Jump(1) and Jump(2) are the only
valid jumps. Being able to help the compiler by expressing
such constraints at the language level would be even more
amazing but that is a whole other topic.<br>
</div>
<div><br>
</div>
<div>Would something like this be possible one day?<br>
</div>
<div><br>
</div>
<div>
<div>
<div>
<div dir="ltr" class="gmail_signature">
<div dir="ltr">
<div>Regards<br>
</div>
<div>Swaranga</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<br><br></blockquote></div></div></body></html>