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



Reply via email to