----- Mail original ----- > De: "Brian Goetz" <brian.go...@oracle.com> > À: "Remi Forax" <fo...@univ-mlv.fr> > Cc: "Guy Steele" <guy.ste...@oracle.com>, "Alan Malloy" <amal...@google.com>, > "amber-spec-experts" > <amber-spec-experts@openjdk.java.net> > Envoyé: Mardi 8 Septembre 2020 15:53:36 > Objet: Re: Is case var(var x, var y) a valid syntax ?
>> - Is either total or partial. Deconstruction patterns are total; other >> patterns >> we'll be able to express later, such as `Optional.of(var x)`, are partial. > > While I don’t want to get into a deep dive on declared patterns now, let’s > just > say that they’ll exist and they’re important (Optional.of(var x), > Optional.empty(), etc.) So in increasing order of generality: > > Type patterns: T t > Deconstruction patterns: T(var x) > Declared patterns: Optional.of(var x) > > Remi would like to view deconstruction patterns as a generalization of type > pattern, but they are more properly understood as a restriction of declared > patterns — just as constructors can be understood as a restriction of methods. > Because we haven’t seen much of declared patterns yet, it is easier to miss > their role in the spectrum, but their role is pretty obvious once you step > back > and think about it. see below > > Deconstruction patterns are constrained compared to declared patterns in: > > - their name (like constructors!) > - They are total on their declaring class, so they are guaranteed to match > (much > like a constructor is guaranteed to not return null) > - While instance members, they are not inherited (just like constructors) At least you want a deconstructor to be overrideable (which is not fully equivalent to being inherited). A deconstructor is for allowing encapsulation so the world projected by a deconstructor may have a little to share with how the the class are implemented class Employee { int baseSalary; deconstructor Employee(int salary) { return (baseSalary); } } class VP extends Employee { int bonus; deconstructor VP(int salary) { return (baseSalary + bonus); } } ... Vp vp = new VP(); vp.setBaseSalary(2000); vp.setBonus(500); Employee employee = vp; employee instanceof Employee(salary) { System.out.println(salary); // 2500 } and here you can see that Employee(salary) is not a call to the deconstructor but an instanceof Employee + a call to the deconstructor (int salary) ! > - They can only be called via a pattern match (just as a constructor can only > be > called via a `new` operation.) so unlike a constructor that can be called either by a new or by this(...) and super(...) a deconstructor can only be called vua pattern matching. > > The role of a constructor is to take an external state description, validate > and > normalize it, and produce an instance. The role of a constructor is to hide the information of how a class is implemented. Only if all the fields are final it plays the role of the single gated entry point. > The role of a deconstructor is to take an instance and produce an external > state > description. (If the ctor has to copy mutable elements on the way in, the > dtor > is also likely to want to do the same on the way out.) The role of a deconstructor is to hide the information of how the class is implemented and allow to pattern match to a projected form of the instance. > > In this way, both ctor and dtor mediate access between an external API and the > internal representation. It's only true for a constructor if the constructor (constructors) are the only way to change the value of an instance. It's only true for a deconstructor if the deconstructor has a matching constructor I start to think that calling a deconstructor a deconstructor is not the right term because while a constructor and a deconstructor can be dual of each other, this mirroring in not true in the general case, it's only guarantee in the case of record because you have a canonical constructor. Rémi