Method Chaining (enhancing Java syntax)

Michał Kłeczek michal at kleczek.org
Wed Jun 14 19:41:08 UTC 2023


There is also the infamous “double curly brace” idiom:

new UIMultiSelect() {{
  css(“color”, “green”);
  addClass(“attention”);
  maxSelection(3);
}};

I wonder if that could be somehow optimised…

Michal

> On 13 Jun 2023, at 20:09, Attila Kelemen <attila.kelemen85 at gmail.com> wrote:
> 
> Though I'm biased, because I never liked this hack, since it is just hacking the language to help with some inconveniences of the language, otherwise returning "this" is conceptually strange, since an object is returned to me which I clearly already have. Instead of having hacks like this in the language (which would then trigger a lot more questions down the line), if Java wants to address the problem, then the actual issues should be addressed. For example making it possible to build immutable objects with many fields with potential defaults.
> 
> As for your case (since usually the main issue is that you want a single expression), I think it is cleaner to do this:
> 
> Create utility method like this:
> 
> ```
> public static <T> T with(T obj, Consumer<? super T> action) {
>   action.accept(obj);
>   return obj;
> }
> ```
> 
> Which then you could just use this way (using your example):
> 
> ```
> var mySelect = with(new UIMultiSelect(), node -> {
>   node.css("color", "green");
>   node.addClass("attention");
>   node.maxSelection(3);
> });
> ```
> 
> This also avoids the issue with chaining where people tend to nest arguments deeply (when the argument is something built this way as well), because they can't break the chain in the middle (without giving up all the benefits), so just decide to nest arguments causing stack overflow for my brain.
> 
> Attila
> 
> 
> Tomáš Bleša <blesa at anneca.cz <mailto:blesa at anneca.cz>> ezt írta (időpont: 2023. jún. 13., K, 19:17):
>> Hi, 
>> 
>> thank you for comments and references. I didn’t mean we should create special self-type. The proposed syntax:
>> 
>>   public this hello() {}
>> 
>> doesn’t mean “returns an object of the same type as my class”.
>> 
>> but rather
>> 
>> “returns the same instance it is called on”. The fact that it is also the same type is a useful byproduct. Please note that I used lowercase T to emphasize it is the instance not type.
>> 
>> Under the hood nothing has to be returned (on the call stack) and the method should compile to:
>> 
>>   public void hello() {}
>> 
>> That’s why using this (ThisClass/MyClass) in method arguments or other places doesn’t make sense to me. (Passing the same instance to method which already has this reference.) It also doesn’t make sense (or little) to use it on static methods like:
>> 
>>   public static this hello();
>> 
>> Ad Generics) As you pointed out it doesn’t work well with deep class hierarchy and also reduces readability (adds boilerplate). Imagine for example big library representing UI (like DOM structure):
>> 
>> UIElement	// method css(…) here
>>     UILayout
>>         UIGridLayout
>>>>     UIFormElement
>>         UISelect
>>             UIMultiSelect…	// has method maxSelection()
>> 
>> // compilation error
>> var mySelect = new UIMultiSelect().css(„color”, „green”)
>> 	.addClass(„attention”).maxSelection(3);
>> 
>> This is basically my use-case. I have 60..100 subclasses.
>> 
>> Ad "Is the feature important enough?")
>> 
>> Technically all language features are just “a syntactic sugar” to the assembler (bytecode). I lived many years without switch-expressions, try-with-resource,… :-)
>> 
>> All the best,
>> Tomas
>> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/jdk-dev/attachments/20230614/cf212e69/attachment.htm>


More information about the jdk-dev mailing list