Pattern matching on multiple objects

Brian Goetz brian.goetz at oracle.com
Sun Apr 23 15:25:56 UTC 2023


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.


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/528e9eec/attachment.htm>


More information about the amber-dev mailing list