[patterns] primitive widening
Remi Forax
forax at univ-mlv.fr
Sun Oct 15 09:33:12 UTC 2017
I do not think that a Short should matches a long if the pattern matching is defined as a suite of matches, the behavior will be weird.
By example with,
Object x = new Short();
switch(x) {
case long l: ...
case short s: ...
}
it will be surprising that the first case matches.
In my opinion, we should stick to
matches = instanceof + cast
the instanceof part is a plain old instanceof and the cast can be an unboxing but not a widening conversion
so with x an object
x matches long l <=> x instanceof Long + unbox Long
With your example,
void test(Short x) {
assert(x matches long l); // compile error, because x instanceof Long is a compile error
}
regards,
Rémi
----- Mail original -----
> De: "John Rose" <john.r.rose at oracle.com>
> À: "amber-dev" <amber-dev at openjdk.java.net>
> Envoyé: Dimanche 15 Octobre 2017 01:02:14
> Objet: [patterns] primitive widening
> Interesting question: Should a "Short" box value
> match a "long" primitive? More generally, should
> pattern matching emulate assignment conversions?
> Including primitive widening conversions?
>
> Probably the answer is yes, under the theory that
> a pattern match digs through dynamic information to
> search for a *possible* assignment, and then (along
> that "match succeeded" path, is ready to make the
> assignment to a binding variable.
>
> void test(Short x) {
> long y = x; //OK
> longConsumer(x); //OK
> assert(x matches long); //OK??
> }
> void longConsumer(long z) { }
>
> Does the prototype work that way? No, there is just an
> open-coded instanceof test of the wrapper type
> (makeTypeTest … boxedTypeOrType).
>
> This is tricky to implement dynamically, but MH.invoke
> gets these details correct already, since it makes a
> dynamic emulation of (many of) Java's static rules for
> method argument conversion.
>
> ("Many of" means that the dynamic emulation is aware
> only of reified types, as if only raw types were present.
> Happily, the Core Reflection API also does the same
> emulation, although with different exceptions thrown.)
>
> These are the relevant routines from the MH runtime:
> sun.invoke.util.Wrapper::isConvertibleFrom
> sun.invoke.util.Wrapper::convert
>
> One good thing about this messy stuff: The widening
> primitive conversions (and narrowing ones, in the case
> of a cast) only come into play when the target type is
> really a primitive, not just a reference wrapping one.
>
> So we don't have to match a Short to a Long, just
> a Byte, Short, Character, Integer, Float, and Long to
> a primitive long (if the source type is a reference
> type that can contain any or all of the above).
>
> A factored runtime for pattern matching will be able
> to use the MH routines, if we decide that's the correct
> behavior. By "factored runtime" I hope for, of course,
> something with a metafactory for each switch and
> pattern.
>
> — John
More information about the amber-dev
mailing list