<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<font size="4"><font face="monospace">I'm going to try and address
these points *for the benefit of everyone else*. (Note to Remi
only: this is not an invitation to continue the back and forth,
as doing so would likely be unconstructive unless you have
something either (a) radically new that no one has thought of
yet and/or (b) something that is so obviously right and
compelling that I will immediately weep with embarrassment for
how wrong I was. That's the bar at this point. I get that you
hate this feature. You've made that manifestly clear. But
unless you have some significantly new light to shed on it, it
is unconstructive to just keep banging this drum, and you are
creating an environment where others feel less comfortable
sharing their thoughts, which is unacceptable.) <br>
</font></font><br>
<blockquote type="cite" cite="mid:27437ad6-7a87-580f-a593-9866f1ee8af5@oracle.com">1)
having a primitive pattern doing a range check is useless because
this is rare that you want to do a range check + cast in real
life,
<br>
How many people have written a code like this
<br>
<br>
int i = ...
<br>
if (i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE)
{
<br>
byte b = (byte) i;
<br>
...
<br>
}
<br>
<br>
It's useful when you write a bytecode generator without using
an existing library, ok, but how many write a bytecode generator ?
<br>
It should not be the default behavior for the primitive type
pattern.
<br>
</blockquote>
<br>
This argument stems from a misunderstanding of what we are trying to
accomplish here. Yes, it is correct that `case byte b` is not
something everyone will use (I have written this many times, though
I admit this is probably unusual.) But that's not the point of this
exercise; the point of the exercise is uniformity, in part because
the lack of uniformity is complexity, and in part we want to offer
new semantic symmetries that programmers can count on. You are
trying to tinker at the margins, asking if each conversion carries
its weight; that's a recipe for creating new, ad-hoc complexity
surface. Sometimes that's the right move, and sometimes it is
unavoidable, but there is such an obviously correct interpretation
of primitive instanceof here -- "would a cast to this type be safe"
-- that it would be an unforced error to opt for the ad-hoc
complexity just because you can't imagine using it that often. <br>
<br>
If I have a record:<br>
<br>
record R(int x) { }<br>
<br>
I can construct it with <br>
<br>
new R(aShort)<br>
<br>
but under the strict semantics of primitive type patterns, I cannot
deconstruct it with<br>
<br>
case R(short s) { }<br>
<br>
which would ask: "could this record have come from a constructor
invocation `new R(s)`". And this is gratuitously different than
the correspond case with reference widening:<br>
<br>
record S(Object o) { }<br>
<br>
S s = new S("foo");<br>
if (s instanceof S(String ss)) { ... }<br>
<br>
Further, I take objection to your continued characterization of this
as a "range check", as this is a mischaracterization as well as
minimizing what is going on. Casting subsumes boxing and unboxing
as well as widening and narrowing, so a more correct
characterization would be "could I cast this without loss or error
to a short". Which applies not only to wider and narrower types,
but to types like Short and Object. Just like `instanceof` for
reference types, which asks whether the type could be cast to
another type. And without creating a new context for what is
allowable. <br>
<br>
Not only is the term "useless" unconstructive, but it is not even
the right measure. The bar here is not "would people use it a
lot." We're making the language simpler by making it more uniform.
To say "let's gratuitously knock some of the boxes out of the cast
matrix because I can't imagine using them" only makes the language
more complicated. <br>
<br>
<blockquote type="cite" cite="mid:27437ad6-7a87-580f-a593-9866f1ee8af5@oracle.com">
2) It's also useless because there is no need to have it as a
pattern, when you can use a cast in the following expression
<br>
Person person = ...
<br>
switch(person) {
<br>
// instead of
<br>
// case Person(double age) -> foo(age);
<br>
// one can write
<br>
case Person(int age) -> foo(age); // widening cast
<br>
}
<br>
</blockquote>
<br>
Same argument (also you got your example backwards). I get that you
think its fine to have to do this, but it is yet another gratuitous
asymmetry between aggregation and destructuring that confuses people
about how destructuring works. Why can you pass an int or a double
to `new Person`, but could only take an `double` out? Whereas with
Object/String, you could take either out? <br>
<br>
Again, this is gratuitous complexity, which I think is rooted in
your unwillingness to let go of "instanceof means subtype." Sorry,
it doesn't any more (but it means something that generalizes it.) <br>
<br>
<blockquote type="cite" cite="mid:27437ad6-7a87-580f-a593-9866f1ee8af5@oracle.com">
3) when you read a conditional primitive patterns, you have no
idea what is the underlying operation until you go to the
declaration (unlike the code just above).
<br>
</blockquote>
<br>
This is the same complaint you had in the past about partial and
total nested patterns. As I've said, I understand why you find it
uncomfortable ("action at a distance"), but we evaluated the pros
and cons extensively already, and we made our decision. There's no
reason to reopen it here, nor are the considerations any different
in this case. <br>
<br>
<blockquote type="cite" cite="mid:27437ad6-7a87-580f-a593-9866f1ee8af5@oracle.com">
4) if we change the type pattern to be not just about subtyping,
we should revisit the JLS to avoid to have too many different
semantics.
<br>
</blockquote>
<br>
This is FUD, implying that we are going to have to reexamine
everything. I don't buy it. Many of the things that lean on
subtyping today are just ... subtyping. And the things that have
conversions involving primitives already lean on conversions and
contexts. <br>
<br>
By way of concrete example, you raised the question about covariant
overrides. Which was a good example, and which I appreciate, but I
wish you would have raised it differently. <br>
<br>
A constructive way to raise this would be: "Do we also want to
reexamine covariant overrides to use castability (or some other
criteria) rather than subtyping?" <br>
<br>
An unconstructive way to raise this would be: "This feature is bad,
look at the problems you are creating for covariant overrides,
everything will have to be reexamined." <br>
<br>
<br>
</body>
</html>