[External] : Re: Draft JEP on Primitive types in patterns, instanceof, and switch

Ron Pressler ron.pressler at oracle.com
Fri Jan 27 12:01:41 UTC 2023



> On 27 Jan 2023, at 11:06, Remi Forax <forax at univ-mlv.fr> wrote:
> 
> The problem with extrapoling/re-interpreting is where to stop, where to draw the line.
> Most languages that have C as ancestor have tried to separate the different casts into different categories, considering using the same syntax for different kind of casts as a mistake. 
> Re-interpreting "instanceof" as a question if any casts will succeed and not just reference casts is a huge leap of faith that feels backward.

There are obviously multiple ways to extrapolate and generalise things “correctly.” Whatever the generalisation is, opinions on how it feels may vary. The more interesting question is, I think, does the proposes approach lead to actual problems, not whether or not it’s the only possible one.

> 
> Generations of Java developers have a pretty good grasp of the difference between subtyping and primitive conversions, this proposal acts as a wrecking ball and shatter that.

§4.10.1 of the JLS has stated that a subtyping relationship among primitives exists (byte <: short <: int <: long, float <: double) since at least Java 1.6 (possibly earlier).

> By example, you can not override a method that returns a double with a method that returns an int because overriding is about subtyping relationship, not conversion (for the history, Neal Gafter had implemented method overriding that allow primitive conversions in javac in one of the early versions of Java 1.5 but to it was decided to not go that path).

The rules for return types in overridden methods (§8.4.8.3) doesn’t refer to subtyping but to "return-type-substitutability” (§8.4.5) which, in turn, also doesn’t talk about subtyping but only about subtyping *in the case that the return type is a reference type*. So even though there is a subtyping relationship between int and long (though not between int and double), they are not return-type-substitutable, which places additional constraints beyond mere subtyping.

> 
> I agree that revisiting concepts is something we have to do, but breaking the difference between subtyping and primitive conversions for a corner case, in isolation, is a decision hard to understand.


First, a subtyping relationship for primitives does exist, though it doesn’t cover all of the possible conversions.
Second, nothing is broken, shattered, or wrecked even in cases subtyping doesn’t exist, because the draft doesn’t propose to *change* the meaning of patterns, but rather to generalise them. I.e. its insight is that subtyping is a special case of assignment conversion, and so patterns are “really” about the validity of such conversions rather than about the specific case of subtyping.

Another way of looking at it is that switch has always been about switching on specific values. Patterns generalise the switch cases to cover a set of values rather than individual ones, where the set of the values covered by the case is the set of all instances of a type. This proposal generalises patterns to further allow other kinds of sets (and, at least in some of those situations, still uses the subtyping relationship even on primitives).

I think it’s clear that nothing here is “broken” or even changed; just generalised in a particular way. We can argue over whether this particular generalisation feels philosophically satisfying (although I think much of it has to do with personal aesthetics), but there is no definitively right or wrong answer, because things can be generalised and extrapolated in many sound ways. It would be helpful, therefore, to explain whether an objection stems from “aesthetic unease” due to philosophical opinions about the generalisation or a concrete problem that may arise.

— Ron


More information about the amber-dev mailing list