Adding Do notaion/For comprehension

Remi Forax forax at univ-mlv.fr
Sat Nov 14 22:54:05 UTC 2020


Wrong mailing list. 

> De: "Nikita Eshkeev" <neshkeev at yandex.ru>
> À: "compiler-dev" <compiler-dev at openjdk.java.net>
> Envoyé: Samedi 14 Novembre 2020 22:58:53
> Objet: Adding Do notaion/For comprehension

> Hi,
> What do you think about adding a language feature that is similar to do-notation
> in Haskell or for-comprehension in Scala to make it easier to work with nested
> flatMap?

Language construct like for(:) or try(...) {} use an interface as type support, so even if we wanted to add that feature, 
we first need to be able to abstract Optional or Stream to a common interface containing flatMap(), something we can not do in Java, you have to put the type system on steroid first. 

> In java 5 we extended the capabilities of the for loop to iterate over types
> that implement Iterable now I propose to add a language feature that will
> simplify the code with nested flatMap, for example, the following code:
> Optional<String> helloWorld = Optional.of("Hello")
> .flatMap(hello -> Optional.of("World")
> .flatMap(world -> Optional.of(hello + ", " + world + "!")))
> would be transformable a more cleaner version:
> Optional<String> helloWorld = for {
> hello <- Optional.of("Hello");
> world <- Optional.of("World");
> Optional.of(hello + ", " + world + "!")
> }
> *Here the word "for" is used as an example, it can be something different.

A more Java like syntax should be something like 

Optional<String> helloWorld = 
do(var hello = Optional.of("Hello"); 
var world = Optional.of("World")) { 
yield Optional.of(hello + ", " + world + " !"; 
}; 

> I would like to hear your opinion on it.

I'm not seeing flatMap() being used often enough in Java code to the point it requires it own syntax. 
It's conceptually cool to see that flatMap() on a Stream and a loop are two sides of the same coin, but is it that useful ? 

Also, in the case of Optional, we may also be able to express the same snippet using pattern matching 

Optional<String> helloWorld = 
switch(Optional.of("Hello"), Optional.of("World")) { 
case (Optional.of(var hello), Optional.of(var world)) -> Optional.of(hello + ", " + world + " !"); 
default -> Optional.empty(); 
}; 

and even 
Optional<String> helloWorld = 
switch(Optional.of("Hello"), Optional.of("World")) { 
case (of(var hello), of(var world)) -> Optional.of(hello + ", " + world + " !"); 
default -> Optional.empty(); 
}; 

If we decide that like you don't have to specify the type of the enum when you match an enum constant, you don't have to specify the type when you match using a "named" deconstructor. 

> Sincerely,
> Nikita Eshkeev

Rémi 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20201114/85ba5f87/attachment-0001.htm>


More information about the amber-spec-experts mailing list