> De: "Brian Goetz" <[email protected]>
> À: "Remi Forax" <[email protected]>
> Cc: "amber-spec-experts" <[email protected]>
> Envoyé: Jeudi 13 Août 2020 15:42:40
> Objet: Re: A peek at the roadmap for pattern matching and more
>> We want a destructor, a destructor is a method that returns a list of values
>> the
>> same way a constructor takes a list of parameters.
>> The way to represent that list of value is to use a record.
> Yes, already been down that road, I did an entire sketch of this feature where
> we expose “anonymous records.” It felt really cool — for about five minutes.
> The conclusion of this exercise was that in this case, records are better as a
> _translation mechanism_ than a surface syntax.
first why ? and second, my experience is the opposite, the more there is a
difference between Java the language and the translation strategy the more it
will bite you with corner cases.
> So yes, the way to represent it is a record, but in the class file, not the
> language.
>> So we can already write a de-constructor with the current version of Java,
> As you figured out, if you cast a deconstructor as a method with a special
> name,
> you say goodbye to deconstructor overloading. And if you do make it magically
> overloadable, then it's magic,
It's not magic, it's a translation strategy like the same way with bridges, you
can have methods with the same name and different return types.
> and you’ve lost all the benefit off pretending its a method. You just moved
> the
> complexity around. And again here comes that glass half empty feeling: “Why
> can
> I only do it with this method?”. Much better to recognize that deconstruction
> is a fundamental operation on objects, just like construction — because it is.
But constructors are plain methods with some special bells and whistles (funny
names, funny rules for the initialization of this and final fields, etc).
Having a deconstructor being a method with several overloads doesn't strike me
as very magic compared to a constructor.
And you can not have several overloaded methods with different return types
because Java like C doesn't force you to specify the return type of a method
call. So unlike with a pattern where you provide the type, you don't provide
the return type when you do a method call.
>> i should wuth by example a method minMax that returns both the minimum and
>> the
>> maximum of an array
>> public static (int min, int max) minMax(int[] array) {
> Nope. Not going there. I went down this road too, but multiple-return is
> another
> one of those “tease” features that looks cool but very quickly looks like
> glass
> 80% empty. More fake tuples for which the user will not thank us. And, to the
> extent we pick _this particular_ tuple syntax, the reaction is “well then WTF
> did you do records for?”
Records are the underlying type used by the tuple syntax.
The tuple syntax is as its name suggest, just a syntax. From the semantics POV,
it's an anonymous record, thus, not a structural type.
You may use a record instead of an anonymous record, if you want to reuse the
same record for multiple deconstructor, if i have several classes representing
rectangular shape, i may want them to share the same record.
It's really very similar to the difference between a method reference and a
lambda or a classical class and an anonymous class. A record is explicitly
named, it can have annotations, it can be serializable, implements interfaces,
have it's own toString() etc. An anonymous record is the anonymous version of a
record, where you don't care about the name or resource sharing (on record per
deconstructor).
> Having records _and_ structural tuples would be silly. We’ve made our choice:
> Java’s tuples are nominal.
But the syntax you are proposing for deconstruction is using the syntax of a
_structural tuples_ . Here the glass is half empty, because why the
deconstructor can have that feature and not any methods given that at the end a
de-constructor is desugared as a method that return a record. As i said in my
original mail. I agree with you that we don't want a _structural tuples_, but
it's not, it's an anonymous record and restricted them only to deconstructor
does not make make a lot of sens.
I's like saying look this shinny anonymous record, deconstructor can use them
but not regular methods.
> Worse, it only addresses the simplest of patterns — deconstructors — because
> they are inherently total. When you get to conditional patterns
> (Optional.of(var x)), you want to wrap that record in something like an
> optional. If the return value is fake, now you have to deal with the
> interaction of trade tuples and generics. No thank you.
I don't see the issue here, where is the problem with the following code ?
Optional<(int x, int y)> deconstructor() {
return Optional.of( (this.x, this.y) );
}
Maybe users will find the syntax weird ? But it's like any new feature ?
I believe you are thinking that the type (int x, int y) is a tuple while
technically it's an anonymous record, so from the type system POV it acts as a
record, i.e. a nominal class.
> Believe me, I’ve been down ALL of these roads.
>> the compiler will generate a synthetic record, so the generated code is
>> equivalent to
> The synthetic record part is the part I liked, and kept.
> There’s room for an “anonymous tuple” feature someday, maybe, but we don’t
> need
> it now.
I'm not suggesting to introduce an anonymous tuple, as you said above, we have
decided to use record instead, a nominal type.
I'm suggesting to introduce the concept of anonymous record, which is what the
synthetic record is, because i see no point to restrict it only to
deconstructors.
> I’m willing to consider the “record conversion” when we get to collection
> literals, but not now.
To represent the couple key/value i suppose.
I don't disagree, but i don't think it's wise to introduce the idea of a
synthetic record without the notion of anonymous record, but we don't need a
synthetic record for deconstructors, it's nice to have but not an essential
part of the design.
Rémi