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