Primitives in instanceof and patterns
Brian Goetz
brian.goetz at oracle.com
Mon Sep 12 22:48:42 UTC 2022
>> (When we get to overloading deconstruction patterns, we'll have all the
>> same issues as we have with overloading methods today -- it is not
>> obvious looking only at the call site, which overload is called, and
>> therefore which conversions are applied to arguments or returns.)
> We do not need overloading of patterns !
> I repeat.
> We do not need overloading of patterns !
You would be incorrect about that.
Deconstruction patterns are the dual of constructors. Pairing a
constructor (or factory) with a deconstruction (or static) pattern forms
an embedding-projection pair, which is what drives, e.g., the `with`
construct. This is a very powerful relationship. Constructors can be
overloaded; saying "but deconstructors can't" is just a gratuitous
restriction, and it undermines the role of patterns as the dual of
ctors/methods.
At the risk of repeating myself, it is clear that you just want pattern
matching to be a much smaller feature. That's a valid opinion, but
please stop with the "not a good idea" / "not needed" / "useless" /
"YAGNI" at every turn. There's a big story here; you can agree with it
or not, but please, please, please stop trying to talk down every part
of the story because it seems "too big" to you. If you don't understand
the big story, ask (constructive) questions. But please, please, stop
trying to YAGNI away everything. It's not helpful.
> Nope,
> let me recapitulate.
>
> 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,
> How many people have written a code like this
>
> int i = ...
> if (i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE) {
> byte b = (byte) i;
> ...
> }
>
> It's useful when you write a bytecode generator without using an existing library, ok, but how many write a bytecode generator ?
> It should not be the default behavior for the primitive type pattern.
>
> 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
> Person person = ...
> switch(person) {
> // instead of
> // case Person(double age) -> foo(age);
> // one can write
> case Person(int age) -> foo(age); // widening cast
> }
>
> 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).
>
>
> 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.
>
Thanks for stating your concerns succinctly. (Some of this is just
subjective "I want patterns to be a smaller feature"; some is
disagreement with decisions that are already made.)
More information about the amber-spec-observers
mailing list