implicit 'return this' JCP suggestion

Remi Forax forax at univ-mlv.fr
Thu Jul 22 20:31:35 UTC 2021


----- Original Message -----
> From: "Brian Goetz" <brian.goetz at oracle.com>
> To: "Scott Morgan" <scott at adligo.com>, "discuss" <discuss at openjdk.java.net>
> Sent: Jeudi 22 Juillet 2021 18:07:02
> Subject: Re: implicit 'return this' JCP suggestion

> This is well-traveled ground.
> 
> Clearly you could write your setter to return its receiver with today's
> language.  In reality, the elision of 'return this' is a pretty small
> benefit; in reality, the ihe implicit goal of your proposal is to make
> the transition from void-return to self-return for _existing libraries_
> a _binary-compatible_ change, by having self-return be handled on the
> client side (permission to reuse the receiver).
> 
> But this still has a deficit, which is that libraries must explicitly
> perform the migration from void-return to self-return, and many will
> not, either because they have other priorities, or because they don't
> want to tie themselves to the Java 18+ classfile version (limiting the
> applicability of their library.)  This means that it will be the better
> part of a decade before most libraries have migrated, with the result
> that an inconsistent mix of libraries will support it, to the
> frustration of users.
> 
> An alternate approach that has been floated is to simply permit
> client-side receiver chaining on void-return methods:
> 
>    foo.setX(3).setY(4)
> 
> by simply reusing the receiver when chaining void methods.
> 
> But still, this has a deficit; the real payoff for such a feature would
> be that one could create, set up, and return an object _in a single
> expression_.  The above only gets us halfway there; instead of:
> 
>    Foo f = new Foo();
>    f.setX(3);
>    f.setY(4);
>    use(f);
> 
> we can do:
> 
>    Foo f = new Foo();
>    f.setX(3).setY(4);
>    use(f);
> 
> But this only eliminates the lesser of the annoyances; the biggie is
> that we cannot create the Foo and initialize it in one go:
> 
>     use(new Foo().setX(3).setY(4).WHAT_GOES_HERE())
> 
> To get there, we'd have to further interpret x.m(), where m() is a void
> method, as evaluating to x:
> 
>     use(new Foo().setX(3).setY(4))
> 
> which is now a more invasive change (and conflicts with the desire to
> make `void` an actual type under Project Valhalla.)
> 
> Further, under such a scheme, it is likely that existing API decisions
> will give users grief.  For example, Collection::add is not a void
> method, it returns a boolean indicating whether a change was made or
> not.  So users will surely try:
> 
>     new ArrayList<>().add(3).add(4)
> 
> and be surprised it doesn't work.  (Moral: mid-game rule changes are
> always more disruptive than you think.)
> 
> In summary, while the goal of this proposal is well-intentioned, and
> parts of the proposed solution are workable, when you work through the
> details, you end up somewhere that is more invasive than expected, for a
> relatively small benefit.

Also, the builder patterns is used more in Java than in other languages because there is no keyword arguments in Java.

As part of Amber, it would be cool to have a way to match Map entries, this can be done using an ad-hoc syntax but it can also be done by saying that exactly like we use the dual of the varargs syntax to match arrays, we should use the dual of the keyword argument syntax to match Map entries.
So introducing both a keyword argument syntax and a keyword matching syntax at the same time may make sense.

Rémi

> 
> 
> On 7/21/2021 7:22 PM, Scott Morgan wrote:
>> Hi All,
>>
>>    I have a JCP suggestion (between my first and 2nd signatures below), and
>> I am wondering if anyone on this list can submit it on my behalf, or if
>> they are interested in collaboration on it.
>>
>> Cheers and TIA!,
>> Scott
>>
>> Summary
>>
>> -------
>>
>>
>>
>>    Implicit return of this;
>>
>>
>>
>>    Provide better syntactic sugar for method chaining in Java, through
>> allowing the 'this' keyword to be used
>>
>> in the return class slot of Java methods.  In addition methods marked as
>> returning 'this' would implicitly return
>>
>> this with out the explicit 'return this;' statement at the end of the
>> method.  For example;
>>
>>
>>
>> public interface MyInterface {
>>
>>    this setFoo(String foo);
>>
>> }
>>
>>
>>
>> public class MyClass implements MyInterface {
>>
>>    private String foo;
>>
>>
>>
>>    public this setFoo(String foo) {
>>
>>      this.foo = foo;
>>
>>      //note the implicit return this;
>>
>>    }
>>
>> }
>>
>>
>>
>> public class MyChildClass extends MyClass  {
>>
>> // NO NEED FOR THIS METHOD NOW YEA, it now returns MyChildClass!
>>
>> //  public MyChildClass setFoo(String foo) {
>>
>> //    super.setFoo(foo);
>>
>> //    return this;
>>
>> //  }
>>
>> }
>>
>>
>>
>> Goals
>>
>> -----
>>
>>    The primary goal is to make Java easier to use, less typing required and
>> improved readability.
>>
>> Removal of repetitive code.
>>
>>
>>
>> Non-Goals
>>
>> ---------
>>
>>
>>
>>    This is not designed to promote method chaining, as that is subjective.
>> However for the developers
>>
>> who like method chaining, it should improve their experience with Java.
>>
>>
>>
>> Success Metrics
>>
>> ---------------
>>
>>
>>
>>    Take a vote of JCP members to see if they think this is a good idea, for
>>
>> developer productivity with the language.
>>
>>
>>
>> Motivation
>>
>> ----------
>>
>>
>>
>>    I have been spending a lot of time overriding methods in child classes in
>> order to
>>
>> make all of the methods return the same type.  This creates a lot of nearly
>> identical
>>
>> code, violating the DRY principles (don't repeat yourself).  The only
>> difference is the
>>
>> return type in the leaf most class of the class parent child tree.
>>
>>
>>
>> Description
>>
>> -----------
>>
>>
>>
>> I'm hoping someone else will implement this JEP.  However I think
>>
>> it would be fairly straight forward step in the java compilers.
>>
>> When the compiler encounters a 'this' in the return type slot
>>
>> it would return the current class.  For all subclasses and
>>
>> implementations the compiler would have bytecode generated that would
>>
>> call the super method and then return this.
>>
>>
>>
>> Alternatives
>>
>> ------------
>>
>>
>>
>> I haven't considered any alternatives.  The current work around is pretty
>> repetitive.
>>
>>
>>
>>
>>
>> Testing
>>
>> -------
>>
>>    The parent child classes in the Summary of this JEP should suffice.
>>
>>
>>
>> Risks and Assumptions
>>
>> ---------------------
>>
>>    I don't see any risks.  I am assuming that this will NOT require a change
>> to any bytecode,
>>
>> only a change to the language.
>>
>>
>>
>> Dependencies
>>
>> ------------
>>
>>    This would require a change to all Java compliers.


More information about the discuss mailing list