> From: "Brian Goetz" <brian.go...@oracle.com> > To: "Remi Forax" <fo...@univ-mlv.fr> > Cc: "amber-spec-experts" <amber-spec-experts@openjdk.java.net> > Sent: Wednesday, January 26, 2022 3:30:45 PM > Subject: Re: [External] : Re: Patterns and GADTs (was: Reviewing feedback on > patterns in switch)
> I don’t object to having something explicit in the code, but I do object to > having that be unchecked. In the original example: >> <T> T unbox(Node<T> n) { >> return switch (n) { >> case A<T> n -> n.t; >> case B n -> n.s; >> }; >> } > we could cast `n,s` to T, but the compiler would have no reason to believe > that > this is valid, so it would give us an unchecked warning. But the reality is, > we > do have enough information to validate this. Now, I’m not sure if users would > be any happier about > case B n -> (T) n.s > even if they did not get an unchecked warning. Still, a cast is probably > better > than new, narrowly targeted syntax here. > If we’re diffident about refining the type of T, we could consider an implicit > conversion (String can be converted to T in a context where we’ve gathered the > appropriate constraints on T), but this is more complicated, and I’m not sure > users will find it any more understandable. Refining the type is something > that > will make more sense to the user (“I know T is String here!”) than complex > rules about when we can funge T and String. I agree, for the compiler, it should be like adding a constraint T = String. The conversion is an equivalent of String <: T which is only half true. Let start without requiring a cast and see if it's too magical or not. Rémi >> On Jan 26, 2022, at 9:16 AM, [ mailto:fo...@univ-mlv.fr | >> fo...@univ-mlv.fr ] wrote: >>> From: "Brian Goetz" < [ mailto:brian.go...@oracle.com | >>> brian.go...@oracle.com ] >>> > >>> To: "Remi Forax" < [ mailto:fo...@univ-mlv.fr | fo...@univ-mlv.fr ] > >>> Cc: "amber-spec-experts" < [ mailto:amber-spec-experts@openjdk.java.net | >>> amber-spec-experts@openjdk.java.net ] > >>> Sent: Wednesday, January 26, 2022 1:28:19 PM >>> Subject: Re: [External] : Re: Patterns and GADTs (was: Reviewing feedback on >>> patterns in switch) >>>> The instanceof example is not a source backward compatible change, >>>> remember that >>>> instanceof is not a preview feature. >>> I’m well aware, can you give an example where flow typing of *type variables >>> only* might lead to incompatibility? (I’m aware that this is a possibility, >>> but >>> you’re stating it like its a fact already on the table.) For example, where >>> it >>> would change overload selection (this is where flow typing for variables >>> falls >>> down, among other places.) >> sure, >> sealed interface Node<T> { } >> record A<T>(T t) implements Node<T> { } >> record B(String s) implements Node<String> { } >> void foo(Object o) { } >> void foo(List<String> list) { } >> <T> void m() { >> if (node instanceof B b) { >> foo(List.<T>of()); >> } >> } >> Rémi