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. On Jan 26, 2022, at 9:16 AM, fo...@univ-mlv.fr<mailto:fo...@univ-mlv.fr> wrote: ________________________________ From: "Brian Goetz" <brian.go...@oracle.com<mailto:brian.go...@oracle.com>> To: "Remi Forax" <fo...@univ-mlv.fr<mailto:fo...@univ-mlv.fr>> Cc: "amber-spec-experts" <amber-spec-experts@openjdk.java.net<mailto: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