Pattern matching on multiple objects

Remi Forax forax at univ-mlv.fr
Sun Apr 23 19:49:43 UTC 2023


> From: "Brian Goetz" <brian.goetz at oracle.com>
> To: "Swaranga Sarma" <sarma.swaranga at gmail.com>, "amber-dev"
> <amber-dev at openjdk.java.net>
> Sent: Sunday, April 23, 2023 5:25:56 PM
> Subject: Re: Pattern matching on multiple objects

> There was some brief mention in an earlier document about this as a possible
> long-term future feature.

> 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 :)

> String fizzBuzz(int i) {
> return switch (i % 5, i % 3) {
> case (0, 0) -> "FizzBuzz";
> case (0, _) -> "Fizz";
> case (_, 0) -> "Buzz";
> default -> String.valueOf(i);
> }

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

> So the answer is maybe, someday.
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"), 

static String fizzBuzz(int i) { 
record $(int d5, int d3) {} 
return switch (new $(i % 5, i % 3)) { 
case $(var d5, var d3) when d5 == 0 && d3 == 0 -> "FizzBuzz"; 
case $(var d5, var __) when d5 == 0 -> "Fizz"; 
case $(var __, var d3) when d3 == 0 -> "Buzz"; 
default -> "" + i; 
}; 
} 

regards, 
Rémi 

> On 4/23/2023 7:19 AM, Swaranga Sarma wrote:

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

>> Simplified sample code that I wish to be able to write (although the point is
>> not the exact syntax):
>> sealed interface State {} record Start() implements State {} record First()
>> implements State {} record Second() implements State {} record End() implements
>> State {} sealed interface Move {} record Jump( int steps) implements Move {
>> Jump { if (steps < 0 || steps > 2 ) throw new IllegalArgumentException(); } }
>> record None() implements Move {} State transition (State initial, Move move) {
>> return switch (initial, move) { case (Start, Jump( 1 )) -> First; case (Start,
>> Jump( 2 )) | (First, Jump( 1 )) -> Second; case (First, Jump( 2 )) | (Second,
>> Jump(_)) -> End; case (End, _) -> End; case (None, _) -> initial; } }

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

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

>> Would something like this be possible one day?

>> Regards
>> Swaranga
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20230423/61d9f396/attachment-0001.htm>


More information about the amber-dev mailing list