Someone is confused by pattern matching (was: Pattern matching on primitive types mxied with instanceof is a footgun)

Brian Goetz brian.goetz at oracle.com
Wed Feb 5 06:24:05 UTC 2025


Let’s dig in and see if we can find what’s really bothering you here.  (But, the clickbait subject and the escalation from “someone was confused” to “so let’s take it out” is surely not helping, so let’s leave that behind.)

For me it's more about the conversion being implicit vs explicit.

But, I’m not seeing an implicit conversion.  I’m seeing an *explicit* one.

If I say

    float f = …
    Int i = f

The conversion here is both implicit and *lossy*.  (I would be sympathetic if you were saying that lossy assignment conversion was troubling; this is a feature that we copied too-literally from C, and this is arguably a mistake.). But if I say

    If (f instanceof int i) { … }

The conversion looks pretty explicit to me, and it is never lossy.  This is strictly better than either of the alternatives (don’t allow the pattern match at all, in which case the only conversion available to the user is an unsafe cast, or always allow it but accept silent information loss.).  Further, I think a great deal of the discomfort here is that we’re still getting used to it.  The old way was both inflexible and unsafe, so we’ve gotten used to the idea that “everything about primitives is different.”  Valhalla will bust that wide open soon enough anyway, so there’s no point in trying to cling to the old intuitions about primitives.

The other feature involved is pattern nesting, which is composition; x matches P(Q) when x matches P(a) && a matches q.  We discussed the concerns over “action at a distance” endlessly in the first go-around; some people were concerned that

    Box<Object> b = …
    If (b instanceof Box(String s)) { … }

Was too subtle, because the declaration and the use of the pattern were “far away” and a reader might not see the conditionality of the nested pattern.  I’m sympathetic to that, but (a) this is something that one grows more comfortable with with use, (b) IDEs can help by coloring conditional nested patterns differently, (c) the alternative is far less expressive.

What we’re seeing now is merely composing these two features; there’s nothing new here, except that the visual ambiguity between “just unpack the pattern” and “do a nested match” gets combined with the novelty of primitive patterns (which again, take some time getting used to.)

I can see how you would call this an “implicit” conversion, but it’s not any more implicit with primitives as it is with Box(String s).

So I recommend you think long and hard about what is *really* bothering you, and then we can have a conversation about it.





Here, we have an implicit conversion while the conversion does not always succeed.

I believe such conversions, the one that may not always succeed, should be explicit not implicit.

regards,
Rémi

@Brian, i'm more worry about a TA with more than 10 years of experience having trouble to find a bug in a student project written in Java.
@Tagir, i'm not sure usin floating point values is the issue here, you can have the same kind of bug between a character and an int.




On 04/02/2025 16:00, Tagir Valeev wrote:
Hello!

Well, I would say that Remi has a point. This is a silent mistake that can be made. You don't see the declaration, as it's in another file so you may forget about original types and assume that they are ints. The code compiles and doesn't even throw an exception, it just works incorrectly. It would be justified if such code pattern (converting from double to int only when double fits the int) was common, so conditional narrowing could be useful in many other places. But the fact is that it's highly uncommon. Nobody does this. Many other pattern matching features are nice. E.g., I often see the code which can be migrated to pattern switch (we are still on Java 17) and I really want to use it. However, I never see the code which can be migrated to a narrowing primitive pattern.

I don't agree that we should drop primitive patterns completely, but we may reconsider floating point <-> integral conversions and disable them in patterns for a while (enabling them back later will be always possible).

With best regards,
Tagir Valeev

On Tue, Feb 4, 2025 at 12:45 PM Brian Goetz <brian.goetz at oracle.com<mailto:brian.goetz at oracle.com>> wrote:
Wow, that was pretty amazing. You went from “one student, who was never taught about how this works, was confused by it” to “ let’s pull the whole feature “ in one breath.

> On Feb 4, 2025, at 11:33 AM, Remi Forax <forax at univ-mlv.fr<mailto:forax at univ-mlv.fr>> wrote:
>
> Last week,
> one of the TA for the course "OOP using Java" was grading student projects,
> the subject of the project can be summarize to "you are alone in space and angry aliens want you to die".
>
> One of the project had a weird bug when displaying aliens.
> Spoiling the result of bug hunting, this is due to students using the pattern matching on primitive without them realizing it.
>
> Here is a reproducer of the bug:
>
> // in AlienSpaceship.java
> record AlienSpaceship(double x, double y) implements Spaceship {
>  ...
> }
>
> ...
>
> // in a method in another class
>  ...
>  for(Spaceship spacehip : ...) {
>    ...
>    if (spaceship instanceof AlienSpaceship(int x, int y) {
>      // display the alien space ship at (x, y)
>    }
>    ...
>  }
>
> The TA said she was about to give up when she found the issue and that the Java spec should not allow such pattern.
> I agree with here, pattern matching on primitive types is not a feature people ask for and mixed with instanceof it's a footgun.
>
> This feature can be re-introduced later using method patterns and it will be easier to understand the code,
> by example with an hyphotethical method Double.asInt
>
>  if (spaceship instanceof AlienSpaceship(Double.asInt(int x), Double.asInt(int y)) {
>    ...
>
> regards,
> Rémi

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-experts/attachments/20250205/23d06bf8/attachment-0001.htm>


More information about the amber-spec-experts mailing list