#pattern matching and shi

1 messages ยท Page 1 of 1 (latest)

heady hawk
#

I can do structural pattern matching in Java?

little patioBOT
#

<@&987246399047479336> please have a look, thanks.

#

Here is an AI assisted attempt to answer your question ๐Ÿค–. Maybe it helps! In any case, a human is on the way ๐Ÿ‘. To continue talking to the AI, you can use </chatgpt:1108714622413963314>.

#

As of Java 16, structural pattern matching is not natively supported in Java. However, you can achieve similar functionality using libraries like Vavr or JEP 305 (Pattern Matching for instanceof) which provide some level of pattern matching capabilities.

Here's an example of how you can use Vavr to perform pattern matching in Java:

import io.vavr.API;
import static io.vavr.API.*;

public class PatternMatchingExample {
    public static void main(String[] args) {
        Object obj = "Hello";

        String result = Match(obj).of(
            Case($(instanceOf(String.class)), s -> "String: " + s),
            Case($(instanceOf(Integer.class)), i -> "Integer: " + i),
            Case($(), o -> "Unknown type")
        );

        System.out.println(result);
    }
}

In this example, the Match function from Vavr is used to perform pattern matching on the obj variable. The Case function is used to define different cases to match against, and the $() matcher matches any value. The result will be printed based on the matched case.

Note that this is just one way to achieve pattern matching in Java using external libraries. It's important to keep in mind that these libraries may have their own limitations and may not provide the full range of features available in languages with native support for structural pattern matching, such as Scala or Kotlin.

heady hawk
#

this isn't what I meant by structural pattern matching

#

I meant something like

switch ((x, y) {
  case (0, 0) -> System.out.println("origin");
  case (0, _) -> System.out.println("y axis");
  case (_, 0) -> System.out.println("x axis");
  default -> System.out.printf("(%d, %d)", x, y);
}
little patioBOT
heady hawk
#

another more useful example is this

#
switch ((is_before_range, is_after_range)) {
  case (false, false) -> System.out.println("all within range");
  case (true, false) -> System.out.println("before and within range");
  case (false, true) -> System.out.println("after and within range");
  case (false, false) -> System.out.println("encapsulates the range");
}
forest trench
#

so first

#

you can do that if you don't have tuples

#

with tuples, you basically can't

#

well, you could use a record and use when or whatever its name is

heady hawk
#

can you elaborate more?

#

I'm a complete java beginner so non of these terms mean anything to me

forest trench
heady hawk
#

the when keyword thing

#

or what a record even is

#

is this some advanced java voodoo?

forest trench
#

kinda

#

a record is like a named tuple

#
record Position(int x, int y) {
}
#

It's like a class

#

But is immutable

#

And has many advantages, like auto creation of constructor, getters, equals, hashcode, toString, and many other interractions with the language

heady hawk
#

I can pattern match the x and y out of it?

forest trench
#

kinda

#

like any object

#

you can simply

#
Position p = new Position(5, 2);
println(p.x());
#

but you can also pattern match on it

heady hawk
#

something of a similar vibe as this

switch ((x, y) {
  case (0, 0) -> System.out.println("origin");
  case (0, _) -> System.out.println("y axis");
  case (_, 0) -> System.out.println("x axis");
  default -> System.out.printf("(%d, %d)", x, y);
}
forest trench
#
Object o = ...
if(o instanceof Position p) {
  println(p);
}
//or
Object o = ...
if(o instanceof Position(int x, int _)) {
  println(x);
}

And it works the same for a switch

halcyon topaz
#

how that?

forest trench
#
switch(o) {
  case Position p -> println(p);
}
// or
switch(o) {
  case Position(int x, int _) -> println(x);
}
// also
switch(o) {
  case Position(int x, int _) when x > 1 -> println(x);
}
#
switch (new Position(x, y) {
  case Position(int x, int y) when x == 0 && y == 0 -> System.out.println("origin");
  case Position(int x, int _) when x == 0 -> System.out.println("y axis");
  case Position(int _, int y) when y == 0 -> System.out.println("x axis");
  default -> System.out.printf("(%d, %d)", x, y);
}

So you could do that, but... at this point, if else is probably better

heady hawk
#

yah the syntax is not great for this

#

haskell is so much better at this

golden radish
#

pattern matching is fairly new to Java and they have to do it right, cause of backwards compatibility

#

therefore u won't see advanced oop concepts in haskell (yet)

#

๐Ÿคทโ€โ™‚๏ธ

halcyon topaz
#

might want to check out JEPs related to pattern matching

scenic bane
#
type Tree a = Node (Tree a) a (Tree a) | Empty
#
sealed interface Tree<T> {}

record Node<T>(Tree<T> left, T value, Tree<T> right)
   implements Tree<T> {}

record Empty<T>()
    implements Tree<T> {}
#

yes, more code

#

but this

#

record Node<T>(Tree<T> left, T value, Tree<T> right)

#

is better for readability and comprehension than

#

Node (Tree a) a (Tree a)

forest trench