Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

How to promote writing real functional style of code in Java  RSS feed

 
Raymond Tong
Ranch Hand
Posts: 255
2
IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi All,

How would you promote to your friends, colleagues, teams to use FP style in Java.
And what kind of best practice / tutorial would you recommend?

There are several ways to write the code to get the same result and people from OO background using stream library but not writing very FP code.
e.g.

Raymond
 
Campbell Ritchie
Sheriff
Posts: 53769
127
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
IntStream.of(1, 13, 42, 7, 37).filter(i -> i < 10).boxed().collect(toList());

You would usually prefix that with

import static java.util.stream.Collectors.toList;
 
Rob Spoor
Sheriff
Posts: 20893
81
Chrome Eclipse IDE Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You should never use approach 2. It's a bad mix of old style looping (body contents) and streams (just the iterating). Either use the stream API completely, or don't use it at all and use a simple loop.
 
Pierre-Yves Saumont
Author
Ranch Hand
Posts: 98
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Using the library developed in my book, this would be:



Note that Java streams allow writing in "functional style", but they are not functional by themselves, being mutable.

It is difficult to provide a simple example in Java 8 because Java 8 elements are not functional (Optional has methods throwing exception, which is probably the most non functional possible feature).

To promote functional programming, I generally use examples showing how errors compose. In standard Java, successes compose well but error don't. In FP, all operations that could produce errors are done inside contexts. As an example, suppose we have three methods producing data needed to construct an object:



In FP, this would be replaced with:



Of course, you would not use Optional since it can't carry the error cause. In my book, I explain how do develop much more powerful contexts than Optional. And beware that one should never access the value from outside the context. So Optional.get() should NEVER be used.
 
Pierre-Yves Saumont
Author
Ranch Hand
Posts: 98
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Another example that people generally appreciate (although it is totally useless) is generating the Fibonacci series:



Note that the Tuple class is not available in Java, but it is very simple. (Many don't like properties named _1 and _2, like in Scala, so you might prefer to call them left and right, or one and two). This implementation is as fast as light and stack safe!
 
Campbell Ritchie
Sheriff
Posts: 53769
127
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Pierre-Yves Saumont wrote:. . .. . .
Nice.

Please tell us more about that List#list method.

Any cows are for general helpfulness in this forum rather than for a specific post. Thank you.
 
Pierre-Yves Saumont
Author
Ranch Hand
Posts: 98
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The List class is a singly linked list I present in the book. The list method is simply a constructor function (not a Java constructor, rather a factory method in legacy Java terms). This method should be named unit (or return, but this is not possible in Java) to respect the functional terminology, but I generally prefer to call unit methods by the name of the class with a lowercase initial, which is compatible with static import. In Scala, such methods are named apply but the language offers syntactic sugar to call them using the name of the class, such as List(1, 13, 42, 7, 37).

Implementing this method in a functional way in Java is tricky. I show a functional implementation in the book, but it is awfully slow. Of course, an imperative implementation (using a loop and mutable variables) is perfectly correct, as long as the method respects referential transparency. A functional implementation would be one using no mutation. It would be difficult not use mutable object, since the argument itself is mutable, but one should not mutate it. A (non functional implementation) could be:



where NIL is a singleton of Nil which is one of the sub classes of List, representing the empty list. Cons is the other sub class representing a non empty list. It is basically:



The real (even less functional) implementation is:



A functional implementation (without using mutation) is possible (using stack safe recursion as I explained in another post):



It has the only (minimal!) inconvenient to be much much slower! (And this is not due to recursion!).

But as I already said, a functional library does not have to have a 100% functional implementation. It only has to offer a 100% functional interface.

By the way, the full List class is available on the FP in java book code github site
 
Campbell Ritchie
Sheriff
Posts: 53769
127
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you
 
Raymond Tong
Ranch Hand
Posts: 255
2
IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Spoor wrote:You should never use approach 2. It's a bad mix of old style looping (body contents) and streams (just the iterating). Either use the stream API completely, or don't use it at all and use a simple loop.

Agree. But I have seen people go with the approach 2 and think it may be even worse than traditional for loop method.
I think the main problems are
- people don't know what methods stream support
- and thinking in OO way to write FP code

Similar for using NoSQL but thinking in RDBMS way.

So, may be learning a pure FP language (ML, Erlang, Haskell, etc.) force you to code in real functional way may help?
 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Raymond Tong wrote:
Agree. But I have seen people go with the approach 2 and think it may be even worse than traditional for loop method.

Maybe, but it is simply more fun.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!