----- 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

Reply via email to