3 ms·
Destructuring is nice, but this here seems to work only in conjunction with instanceof which is a quite rare (and somewhat smelly) operator. I mean, how are yo
by The_Colonel 3y ago
Destructuring is nice, but this here seems to work only in conjunction with instanceof which is a quite rare (and somewhat smelly) operator.
I mean, how are you going to use it? Something like this?
Point p = getPoint();
if (p instanceof Point(int x, int y)) {
System.out.println(x+y);
}
... that seems pretty bad. Or am I missing something?
- the-smug-one 3y agoYou'd do if (getPoint() instanceof ...) if you know it's a Point. But then, you probably don't need to deconstruct it anyway. You can just do p.x+p.y. This type of pattern matching is mostly useful when you have some T and a few cases, there is also a switch/case equivalent for when you've got a lot of them. Maybe we'll see some syntax for deconstructing values directly into variables, a la Python in the future.
- heavyset_go 3y agoYou can have a parent class/interface with many subclasses/implementations. You can then use pattern matching to switch on instances of those subclasses while destructuring objects to access attributes at the same time. Kind of like enums and pattern matching in Rust. In your example there is no reason to use `instanceof` with `p`, you already know what it is.
- The_Colonel 3y ago> You can have a parent class/interface with many subclasses/implementations. Sure, but in Java the standard handling of that is polymorphism. instanceof has been so far a bit of an antipattern, breaking out of the OOP model. > In your example there is no reason to use `instanceof` with `p`, you already know what it is. That's my point. This seems like a very limited version of destructuring if you can use it only when you don't know the type. Like in JavaScript you'd routinely write something like: const {x, y} = getPoint();
- kaba0 3y agoThere is subtyping. A more practical (though not necessarily realistic) example might be: sealed interface List<T> permits Cons<T>, None<T> { record Cons<T>(T head, List<T> tail) {} record None<T>() {} } // some function only wanting the first elem of a list switch (List<T> list) { case Cons<>(T head, var tail) -> // do something default -> {} } If you have used Haskell or similarly strongly typed FP language, you can see how great pattern matching can be.
- heavyset_go 3y ago> Sure, but in Java the standard handling of that is polymorphism. instanceof has been so far a bit of an antipattern, breaking out of the OOP model. I think that's deliberate, Java is moving towards the modern programming zeitgeist that doesn't really care about strict adherence to the OOP model. This is a feature that comes from languages that don't adhere to Java's OOP principles. I didn't downvote you, by the way. Don't know why that happened.
- hibikir 3y agoThe idea is that you deconstruct when a method returns a sum type: An interface with a defined set of implementers that doesn't change. A very common pattern in, say, Haskell or Scala. In Scala you'd also get a warning if you forgot to check one possible type to deconstruct. If you aren't defining your data types like that, yeas, it's a bit weird. This, along with the underscore, and even the sequence type, shows that the language designers are well aware of what Scala does, and are picking and choosing which things to bring in without risking exposing Java devs to the traditional monad salads that you see in many a Scala codebase.
- kaba0 3y agoYou also get compile-time error in Java switch expressions if you are not exhaustive in your cases. But yeah, of course the design team knows about features from Scala, they are probably one of the most competent people on the Earth when it comes to PLs, and are literal CS giants.