Fwd: Concise method bodies with delegation and this

Brian Goetz brian.goetz at oracle.com
Mon Mar 18 14:19:31 UTC 2019


Received on the -comments list.

So, the CMB proposal was a bit of an experiment in letting a half-baked idea out of the lab a little sooner than we usually do.  Since it (for expected reasons) raised some concerns both on the feature itself, and of whether this is the right feature to be working on now, I’m letting it lie fallow for a while.  I think “almost got a consensus, with only one remaining corner” is a little bit of an optimistic description of the status.  

YOu’ve noticed that I sometimes use the CMB syntax in examples; this is both out of convenience (it is a convenient notation) and out of marketing (getting people used to the idea.). I expect the marketing process will take some time, but that’s fine, we’re not going anywhere.

You are right that the really interesting part of the feature is the treatment of “this” when the descriptors don’t already match exactly, and that there’s subtle power in this trick.  And you are right that we are building on an approach that we already started with in lambda, though there are more cases here than lambda handles.  

The trick of building on top of explicit `this` is definitely one of the tools we have in the toolbox.  (While you are correct that the proximate cause for adding it was receiver annotations, we wouldn’t have been so quick to do this if we didn’t see other uses for the same thing in the future, such as such as using it to denote type constraints on conditional methods (e.g., `Foo<T extends Comparable<T>> this)).  

> Begin forwarded message:
> 
> From: Victor Nazarov <asviraspossible at gmail.com>
> Subject: Concise method bodies with delegation and this
> Date: March 12, 2019 at 12:26:07 PM EDT
> To: amber-spec-comments at openjdk.java.net
> 
> There was not much discussion about concise method bodies recently.
> But record discussions usually touches concise methods or silently uses
> concise method declarations in example code.
> 
> As I understand it concise methods almost got a consensus about basic
> syntax and the only remaining corner stone are the details of delegation
> and passing `this` argument to delegated method.
> 
> What I wan't to propose is to left the choice whether to pass `this` as an
> argument or not to user with the help of additional syntax that is already
> present in Java.
> 
> To recall basic syntax uses arrow like lambda expressions and allows to
> define methods without curly braces and return keyword:
> 
>    record Person(String firstName, String lastName) {
>        String fullName() -> firstName + lastName;
>    }
> 
> One of the motivating example of concise methods is an implementation of
> Comparable interface with Comparator;
> 
>    record Person(String firstName, String lastName)
>        implements Comparable<Person> {
> 
>        private static final Comparator<Person> comparator =
>                Comparator.comparing(Person::lastName)
>                        .thenComparing(Person::firstName);
> 
>        String fullName() -> firstName + lastName;
>        int compareTo(Person that) -> comparator.compare(this, that);
>    }
> 
> Delegation form allows to declare method without the need to explicitly
> write method call. `compareTo` implementation becomes:
> 
>    record Person(String firstName, String lastName)
>        implements Comparable<Person> {
> 
>        private static final Comparator<Person> comparator = // ...
> 
>        String fullName() -> firstName + lastName;
>        int compareTo(Person that) = comparator::compare;
>    }
> 
> The problem with delegation form is that sometime it is desireable to pass
> `this` to delegated method, but sometimes it's not:
> 
>    record Person(String firstName, String lastName, List<Person> children)
>        implements Comparable<Person> {
> 
>        private static final Comparator<Person> comparator = // ...
> 
>        String fullName() -> firstName + lastName;
>        int compareTo(Person that) = comparator::compare;
>        int numberOfChildren() = children::size;
>    }
> 
> We want to pass `this` as a first argument into comparator::compare call,
> but we don't want to pass `this` as an argument to children::size call. The
> decision when to pass or not to pass `this` can be left to compiler or more
> specifically to type-checker. But an implementation requires two branches
> of type-inference to be performed. Furthermore both branches can
> potentially succeed and there is no clear criteria what branch should be
> preferred. Additionally this type-inference is inconsistent with type
> inference performed for lambda expressions and method references.
> 
> What I want to propose is to left the choice whether to pass `this` as an
> argument or not to user. What if there is some additional syntax to specify
> when to pass this on delegation or not? But there is already such syntax.
> Java 8 allows `this` to be declared as method parameter (It was done to
> allow custom annotations on this type). The example from above becomes:
> 
>    record Person(String firstName, String lastName, List<Person> children)
>        implements Comparable<Person> {
> 
>        private static final Comparator<Person> comparator = // ...
> 
>        String fullName() -> firstName + lastName;
> 
>        // Here explicit this parameter is declared, so it's passed on to
> delegated method
>        int compareTo(Person this, Person that) = comparator::compare;
> 
>        // Here no explicit this parameter is declared, so it's not passed
>        int numberOfChildren() = children::size;
>    }
> 
> 
> --
> Victor Nazarov

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20190318/4b71b8c8/attachment-0001.html>


More information about the amber-spec-experts mailing list