Java 14 records canonical constructor

Remi Forax forax at univ-mlv.fr
Thu Jun 4 20:30:14 UTC 2020


----- Mail original -----
> De: "Christian Beikov" <christian.beikov at gmail.com>
> À: "Brian Goetz" <brian.goetz at oracle.com>, "amber-dev" <amber-dev at openjdk.java.net>
> Envoyé: Jeudi 4 Juin 2020 22:18:41
> Objet: Re: Java 14 records canonical constructor

> Am 04.06.2020 um 21:39 schrieb Brian Goetz:
>> OK, this seems a totally different question to the one you initially
>> asked :)
>>
>> You're basically saying: why is a record constructor allowed to do
>> _anything_ other than check invariants?
>>
>> I understand where this desire comes from.  But, let's pull on that
>> string.
>>
>> Suppose you want to write a record like:
>>
>>     record Rational(int num, int denom) { }
>>
>> It seems pretty reasonable to want to normalize the numerator and
>> denominator to lowest terms; among other things, this makes it easy to
>> obtain the likely-desired invariant of `new Rational(1, 2)` equals
>> `new Rational(2, 4)`.  Sure, you could export that responsibility on
>> the client, or provide a separate factory `Rational::inLowestTerms`,
>> but surely you see how that is more error-prone.
> 
> Let's say that normalization is allowed in the canonical constructor,
> how would that interact with e.g. pattern matching which I assume is the
> main consumer of the "re-construction" property of records.
> 
> Would the following match the first or the second case?
> 
> switch (new Rational(1, 2)) {
>     case Rational(2, 4):
>         break;
>     case Rational(1, 2):
>         break;
> }
> 

We are starting to be far from the initial thread but this should not compile because new Rational(2, 4).equals(new Rational(1, 2)) returns true,
so your code is equivalent to
  switch(s) {
    case "foo" -> ...
    case "foo" -> ...
  }
which currently doesn't compile.

regards,
Rémi


More information about the amber-dev mailing list