On Tue, Nov 24, 2020 at 10:02 AM Maurizio Cimadamore < [email protected]> wrote:
> > On 24/11/2020 14:45, Remi Forax wrote: > > > > ------------------------------ > > *De: *"Maurizio Cimadamore" <[email protected]> > <[email protected]> > *À: *"Brian Goetz" <[email protected]> <[email protected]>, > "Tagir Valeev" <[email protected]> <[email protected]> > *Cc: *"amber-spec-experts" <[email protected]> > <[email protected]> > *Envoyé: *Mardi 24 Novembre 2020 15:10:35 > *Objet: *Re: Relaxed assignment conversions for sealed types > > > On 31/10/2020 23:30, Brian Goetz wrote: > > > > On Oct 25, 2020, at 10:06 AM, Brian Goetz <[email protected]> wrote: > > To make it clear that I'm not talking about the annoyance of typing the > cast, let's pretend I'm suggesting to write it like this: > > BarImpl bi = (__static BarImpl) b; > > > Pulling on this string some more — I think there’s a connection between > this feature and total statement switches. We’ve been looking for a way to > make statement switches total, and here, what we’re looking for is a way to > make _casts_ total. Which suggests this is one feature, not two. So > perhaps: > > switch-total (x) { … } // a switch, but with added bonus totality > checking > > BarImpl b = (total BarImpl) bar // a cast, but with added bonus > totality checking > > I agree the latter is a common enough problem when writing implementation > code where you have a sealed hierarchy and you know there's only one impl > (Foreign API has this all over the place). > > > You think that not typechecking that BarImpl is the sole implementation of > Bar everytime you write a cast is a problem ? > I don't know for the Foreign API, but having a static helper method that > takes a BarImpl and returns a Bar is not enough ? > > I'm saying that it's (in my humble experience) a common enough pattern > that I've seen often enough, so what Brian is proposing doesn't seem > completely crazy to me - e.g. having some more 1st class support in the > language for this sort of stuff can be a good thing. > > > BarImpl impl(Bar bar) { > return switch(bar) { case BarImpl impl -> impl; }; > } > > Or am i missing something ? > > See first-class :-) Sure, there are other ways to get there. > > > To throw in the mix - how is some kind of pattern match assignment (we > referred to as a "let expression" in some of the earlier docs [1]) would > change the picture here? In other words, maybe it's overloading `=` which > is at odds here, and we need to make it more explicit that this is more > akin to an extraction/match? > > > The match operator (as in let ... match), is more or less what C# as done > by using switch as an operator, > BarImpl impl(Bar bar) { > return bar switch { case BarImpl impl -> impl; }; > } > > It's still a possible syntax for total-switch. > Anyway, it doesn't answer to your question, it seems you want something in > the middle in between a cast and a switch, let impl = bar; > > I think all your references to switch expression reinforce my feeling that > having a pattern-matching based way to declare local variables (as the > document I linked in [1] shows with its __let construct) might be one way > to skin this cat. > > Maurizio > > > Looking at Remi's examples makes me agree more strongly that we need first class support - can't you just hear the resounding "java's too verbose" complaints about having to write the switch helper method and remember to pepper your code with calls to "impl(bar)" rather than using casts as you would elsewhere in your code? I agree Brian's really onto something with suggesting the totality question is the same for the two features. I'm in favour of going even further and removing the cast to allow = to do double duty here for sealed types rather than introducing new syntax for it. The new syntax ("__ construct" or "(total BarImpl)") highlights "this is different" and I'm not sure we need to do that for sealed types. Letting ='s do the work feels like a better form of auto-boxing where javac does the compile-time analysis and errors out for non-total cases or inserts the required total cast for the user. This gives both compile time checking and runtime safety without needing to beat the reader over the head about it. We want to make it easier to read & write correct code - pushing the analysis of totality for sealed types into javac does both for us. --Dan
