Java 14 records canonical constructor
Remi Forax
forax at univ-mlv.fr
Thu Jun 4 20:35:03 UTC 2020
----- Mail original -----
> De: "Remi Forax" <forax at univ-mlv.fr>
> À: "Christian Beikov" <christian.beikov at gmail.com>
> Cc: "Brian Goetz" <brian.goetz at oracle.com>, "amber-dev" <amber-dev at openjdk.java.net>
> Envoyé: Jeudi 4 Juin 2020 22:30:14
> Objet: Re: Java 14 records canonical constructor
> ----- 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.
and i stupidly say should not "compile" but it can not be detected at compile time in Java, so it's more a runtime error, interesting,
because we may instead say that the first that match is the one chosen.
Rémi
More information about the amber-dev
mailing list