Showing posts with label functional programming. Show all posts
Showing posts with label functional programming. Show all posts

09 January 2017

CompletableFuture cheat sheet

I've divided CompletableFuture methods into groups for me easy to remember

Beside the static factory methods that creates a Completable Future instance, here are the following groups

methodparameter expressionsimilar to
// basic
run () -> {}
accept x -> {}
apply x -> y map
compose x -> f2<y>flatMap
// both
run x, f2<?>, () -> {}
accept x, f2<y>, x, y -> {}
combine x, f2<y>, x, y -> z
// either
run x, f2<?>, () -> {}
accept x, f2<x>, (x) -> {}
apply x, f2<x>, (x) -> y
// exceptions
exceptionally x, (ex) -> x
whenComplete x, (x, ex) -> {}
handle x, (x, ex) -> y

We have 4 groups here, basic, both, either and exceptions, and each method of the above can have 3 versions (the main function and one that run async and third one that run async with custom user-provided Executor).

Preface

In functional programming, we have 4 kinds of functional interfaces ( that represents mainly the functions)

void fn ()         => in java called Runnable (implementations of java.lang.Runnable)
void fu (T t)    => in java called Consumers (implementations of java.util.function.Consumer)
U fn (T t)        => in java called Functions (implementations of java.util.function.Function)
U fn()              => in java called Suppliers (implementations of java.util.function.Supplier)

The last type of functions (Suppliers) sometimes are represented by java.util.concurrent.Callable, but Callable returns checked Exception, so Suppliers are more suitable.

In completable future, user can stream over the result and apply different kind of operations on the result (typically as if you use java.util.Stream, and this I see the completable future should have some relation to the Stream interface, I write a little more about this here), and this operation takes a version of the first 3 versions of the functional interfaces above.

Basic Group

The first group, are basic methods, in which the parameter will run on the output object of the completable future instance, for example, apply method (thenApply) with the following signature:

<U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)

This method applies the function in the parameter to the result of type T and return a new object of type U, (hence it is typical mapping function)

Note, the thenApply function has three version, the basic one that run on the same thread as the completable future that has just completes, and 2 version one Async and the other is Async with Executor .

Similar to thenApply are thenRun (3 versions as well) and thenAccept (3 version as well), but thenRun parameter is Runnable which means it expects no input (as result of the completable execution) and return no output.
thenAccept, expects the completable future result as input but returns no output

The last method in this group is thenCompose, which is more or less a flatMap function, which takes the result of the completable future as input and return a CompletableFuture of other type (3 versions as well of this method:

public <U> CompletableFuture<U> thenCompose(Function<? super T,? extends CompletionStage<U>> fn)

Note, CompletableFuture  implements CompletableFuture.

A good use case of thenCompose is when we have a mapping function that will return a CompletableFuture and if we use the regular map function (thenApply), the output will be CompletableFuture<CompletableFuture<U>>. (see the resources for an example).

In this group we could see 4 operations that utilize the first 3 types of functional interfaces, and other groups will keep the same way.

Both Group

The basic group contains the main idea of the whole methods of the CompletableFuture, if you understand it, it will be easy to understand other groups.

Both group is all about, execute the current completable future and then anther completable future (comes as a first parameter to the method), and then the result do with 1 one of 3 things:

Ignore the result and return no output (run)  {method runAfterBoth with 3 versions}
Take the result and return no output (accept) {method thenAcceptBoth with 3 versions}
Take the result and return a new output of different type (combine) (similar to apply in basic group) {method thenCombine with 3 versions}

for example here's the syntax of the thenCombine method:

<U,V> CompletableFuture<V> thenCombine(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)


the method combine the result of the current CompletableFuture with the result of the other CompletableFuture and send them to the function that takes T (type of current compeletable future), U (type of other completable future) and return new type V.

example usage for clarification:

CompletableFuture<String> current = .....
CompletableFuture<Integer> other = .....

current.thenCombine(other, (String s, Integer i) ->  0.99f);

Either Group

Either group is pretty much like the both group, but one of them once executed, the function will be called.

The thing to note here, the combine function name is apply, so why?

apply executed on one of them, combine takes the 2 result and return a new result of new type.

public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T,U> fn)

So, current Completable Future and other completable future should be of same generic type. (T)

Exceptions Group

Exception group are operations that except the completable future will return an exception and will deal with it.

exceptionally: will register function what would happen if exception thrown (to return some value)
whenComplete: will register a consumer of result (might be null) or exception (might be null) (mutual exclusive)
handle: same as whenComplete but register a function instead of a consumer. (to return some value of new type)

simple example on handle:

CompletableFuture.supplyAsync(() -> 10).handle((x, ex)-> "hello" );

Note, although whenComplete takes a consumer function, it returns either the result or the exception thrown.


resources:

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html
http://www.nurkiewicz.com/2013/05/java-8-definitive-guide-to.html




12 October 2016

Using Java 8 Optional and reduce null checking


I am a big fan with the new streams API of Java 8, and I hope it would be used every where in the language.

For example, I hope that, Instead of CompletableFuture interface has  a method named thenApply I hope the name would be "map" instead. and for method like thenAccept, I hope the name would be "forEach" instead.

The point is, thenApply method in the CompleteableFuture interface is more or less a mapping operation, that takes the output of the step before it as input and generates a new output.

Also, theAccept is kind of consumer operation, like forEach, which will will take the output of the previous step as an input and consumes it without generating any output.

And if we talk about the Optional object in Java 8, although I don't have much more functional operations, but he have good enough to allow us to use it to reduce null checking.

The Optional Object has a map and filter (besides its regular methods such as orElseXXX methods).

Here's One example of its usage:

Suppose we have this Object structure that returned from some webservice:

                  static class Result {
Departement departement;
}


static class Departement{
List<Employee> employees;
}


static class Employee{
String name;
}

Then suppose our webservice return the result as one of these 4 functions:

       static Result simulateWsResult1() {
Employee e1 = new Employee();
e1.name = "Ali";
Employee e2 = new Employee();
e2.name = "Muhammad";


Departement dept = new Departement();
dept.employees = Arrays.asList(e1, e2);

Result result = new Result();
result.departement = dept;

return result;
}

static Result simulateWsResult2() {
Employee e1 = new Employee();
Employee e2 = new Employee();

Departement dept = new Departement();
dept.employees = Arrays.asList(e1, e2);

Result result = new Result();
result.departement = dept;

return result;
}

static Result simulateWsResult3() {
Departement dept = new Departement();

Result result = new Result();
result.departement = dept;

return result;
}

static Result simulateWsResult4() {
Result result = new Result();

return result;
}

Then, the main method looks like:

       public static void main(String[] args) {

System.out.println(getEmployeeNames(simulateWsResult1()));
System.out.println(getEmployeeNames(simulateWsResult2()));
System.out.println(getEmployeeNames(simulateWsResult3()));
System.out.println(getEmployeeNames(simulateWsResult4()));
}

And here's the parsing method: getEmployeeNames

       static List<String> getEmployeeNames(Result r){

return
Optional.ofNullable(r)
.map(result -> result.departement)
.map(dept -> dept.employees)
.map(empList -> empList.stream())
.map(empStream -> empStream.filter(e -> e.name != null).map(e -> e.name))
.orElse(Stream.empty())
.collect(Collectors.toList());
}

Complete code here.

Thanks.

02 July 2016

Reduction Operation in functional programming

the operation "Reduce" or "Fold" is a very important operation in functional programming, as you could implement all other operations using the reduce operation. (see ProgFun course at Coursera)

Also, Java tutorial has a very straightforward illustration for Reduction in Java 8: https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html

I want to talk about a case (from cobone-reviews project) that I needed low-level reduction operation.

First I have a Map<Object, List<Long>> that looks like:

{"dp.g.doubleclick.net": [0,1,0,0,0],"cobonereviews.tk": [0,1,0,0,0],"www.facebook.com": [3,4,0,0,0],"www.google.co.in": [0,1,0,0,0],"localhost:8080": [0,0,40,5,3],"l.facebook.com": [0,1,0,0,0],"www.google.com": [0,10,5,0,0],"www.google.com.sa": [0,11,0,0,0],"www.google.com.hk": [0,1,0,0,0],"www.google.ae": [0,3,0,0,0]}
I need to group each top private domain's result together, So the result would looks like:
 {  
   "localhost:8080":[  
    0,  
    0,  
    40,  
    5,  
    3  
   ],  
   "facebook":[  
    3,  
    5,  
    0,  
    0,  
    0  
   ],  
   "google":[  
    0,  
    26,  
    5,  
    0,  
    0  
   ],  
   "cobonereviews":[  
    0,  
    1,  
    0,  
    0,  
    0  
   ],  
   "doubleclick":[  
    0,  
    1,  
    0,  
    0,  
    0  
   ]  
 }  
So first I used the following method to get Top Private Domain from the Map's keys above:
 // Example: www.google.com.sa, google.com, google.eg all translated to  
 // google  
 private String getDomainName(Object referrer) {  
      try {  
           String topPrivateDomain = InternetDomainName.from(referrer.toString()).topPrivateDomain().name();  
           String publicSuffix = InternetDomainName.from(referrer.toString()).publicSuffix().name();  
           String onlyDomainName = topPrivateDomain.replace(publicSuffix, "");  
           return onlyDomainName.endsWith(".") ? onlyDomainName.substring(0, onlyDomainName.length() - 1)  
                     : onlyDomainName;  
      } catch (Exception ex) {  
           log.error(ex.getMessage());  
           return referrer.toString();  
      }  
 }  
Then, I need to use the getDomainName method above as a grouping key and then for the values, I need to concatenate the all lists under the same domain together, for example for case of facebook, I have the following map:
 "www.facebook.com":[   
  3,   
  4,   
  0,   
  0,   
  0   
  ], "l.facebook.com":[   
  0,   
  1,   
  0,   
  0,   
  0   
 ] 
And I need the result to be:

 "facebook":[   
  3,   
  5,   
  0,   
  0,   
  0   
  ]  
So, The reduction method that do the the concat operation looks like:
 collect2.entrySet().stream().collect(groupingBy(e -> getDomainName(e.getKey()),  
  reducing(new ArrayList<Long>(), e -> e.getValue(), (l1, l2) -> accumlateLists(l1, l2))));  
And here's the implementation of accumlateLists method
 private List<Long> accumlateLists(List<Long> accumlator, List<Long> list) {  
      if (accumlator.isEmpty()) {  
           return list;  
      } else {  
           for (int i = 0; i < accumlator.size(); i++) {  
                accumlator.set(i, accumlator.get(i) + list.get(i));  
           }  
           return accumlator;  
      }  
 }  
Note, In the reduction method above, we used the form:
 reducing(U identity, Function<? super T, ? extends U> mapper, BinaryOperator<U> op)  
The first parameter is the accumulator and the zero value (empty ArrayList), the second parameter is mapper, which maps the Entry object to List<Long> which is the object that will be used by the third parameter, hence the mapper Function returns object of type U the same that would be used as type parameter for the BinaryOperator (which is a BiFunction).

Complete source code would be found in this file.

01 January 2015

Progfun: Union two Binary Trees (week 03)

In Progfun assignment of week3 named "objsets", it is required to write some fast-engouh implementation for the union method.

Note, I am here will not show the solution for this question, I'll just give you the key to find the solution yourself.

Here's the Tree objects:

abstract class TweetSet {
    def union(that: TweetSet): TweetSet
    // other methods here..

}

class Empty extends TweetSet {
    def union(that: TweetSet): TweetSet = that
}

class NonEmpty(elem: Tweet, left: TweetSet, right: TweetSet) extends TweetSet {
    // The is the Not-so-fast implementation from the lectures
    def union(that: TweetSet) = ((left union right) union that) incl elem
}

The question again is to find a better solution for the union method (better in terms of performance as the app with such implementation will took too much time to execute)

Well, since I am not so much good in finding a solution in one shot, I go through more than a step..

First I thought in instead of making the `this` tree to include the `that` tree's nodes, I think of the opposite, which is the `that` tree to include the `this` nodes.

I wrote this -not so good -implementation that is coming from (and based on) the foreach implementation; the foreach implementation is:

def foreach(f: Tweet => Unit): Unit = {
    f(elem)
    left.foreach(f)
    right.foreach(f)

}

So, I thought of an implementation like this, but instead of applying some function to each node, no just add each node to `that` tree, So I wrote this initial implementation:

def union(that: TweetSet): TweetSet = {
    var thatVar = that
    this.foreach { x => thatVar = thatVar.incl(x) }
    thatVar

}

WOW, it worked!, So let's enhance it to comply to the courses rules, which among them is don't use vars and use recursion when possible.

The idea above is for each node in the `this` tree, include it to the `that` tree... pretty simple..

To accomplish this by recursion, we need to do the following:

1. `that` should include the element
2. the result of step #1 should be passed again to the recursion method as `that` and ask `left` start the union process over, then ask `right` to start it over again..

def union(that: TweetSet): TweetSet = ??.union(??.union(?? incl elem))

3. replace the ?? above based on your understanding and you will got the solution.






25 May 2013

Java8, my first attempt to write simple lambda (closure)-based example

Java8 will introduce lambda expressions (a.k.a closure), So it will introduce many functional concepts to compete with other powerful langs such as scala.


I've wrote some simple example to show the powerful of functional interfaces and the shortcut syntax of lambda expressions.

I've wrote the example once by Java8 syntax and once by Java7 syntax.



public class HelloJava8{
    public static void main(String[] args){
    
        int v1 = 10, v2 = 30;
    
        int result = performOperation(v1, v2, (a, b) -> a + b);
        System.out.println("result: " + result);
        
        result = performOperation(v1, v2, (x, y) -> x - y);
        System.out.println("result: " + result);
        
        Operation op = (i, j) -> i * j;
        result = performOperation(v1, v2, op);
        System.out.println("result: " + result);
    }

    // funcationl interface, an interface with one method    
    private static int performOperation(int x, int y, Operation op){
        return op.doOperation(x, y);
    }
    
    interface Operation{
        int doOperation(int x, int y);
    }

}

Here's the example with Java7 (notice how Java8 code is much compact):

public class HelloJava7{
    public static void main(String[] args){
    
        int v1 = 10, v2 = 30;
    
        int result = performOperation(v1, v2, new Operation(){
            public int doOperation(int x, int y){
                return x + y;
            }
        });
        System.out.println("result: " + result);
        
        result = performOperation(v1, v2, new Operation(){
            public int doOperation(int x, int y){
                return x + y;
            }
        });
        System.out.println("result: " + result);
        
        Operation op = new Operation(){
            public int doOperation(int i, int j){
                return i * j;
            }
        };    
        result = performOperation(v1, v2, op);
        System.out.println("result: " + result);
    }
    
    private static int performOperation(int x, int y, Operation op){
        return op.doOperation(x, y);
    }
    
    interface Operation{
        int doOperation(int x, int y);
    }

}

29 March 2013

Go functional the Java way (2)

During day job, I've encountered some scenario and I solved it using functional way, I'll show you the problem and my solution to it.


public void updateUserProfile(long userId, UserProfile userProfile){

    String currencyCode = userProfile.getCurrencyCode();
    if (currencyCode != null && currencyCode.trim().length() > 0){
        Util.setCurrency(currencyCode);
    }
    
    String langCode = userProfile.getLangCode();
    if (langCode != null && langCode.trim().length() > 0){
        Util.setLang(langCode);
    }

}


What if some one wants to modify this function to set a new user preferences, and he forget to check the string to be empty?


public void updateUserProfile(long userId, UserProfile userProfile){

    String currencyCode = userProfile.getCurrencyCode();
    if (currencyCode != null && currencyCode.trim().length() > 0){
        Util.setCurrency(currencyCode);
    }
    
    String langCode = userProfile.getLangCode();
    if (langCode != null && langCode.trim().length() > 0){
        Util.setLang(langCode);
    }

    String address = userProfile.getAddress();
    Util.setAddress(address);   // logic error here, the business says, do not ever allow the user to clear the values of his profile throw this method call
}


So, What is the solution?

I think about it, and I imagine it as we need to create a new function that takes the new value as the first parameter, and take the function that need to applied on the value as the second parameter, so the sedo-code will look like:


public void updateUserProfile(long userId, UserProfile userProfile){

    setNewValue(currencyCode, Util.setCurrency);
    setNewValue(langCode, Util.setLang);
}

private void setNewValue(String newValue, Function1<T> f){
    if (newValue != null && newValue.trim().length() > 0)
        f.apply(newValue);
}



But passing functions is not allowed until java8, so, I had to use interfaces for this functionality:


public void updateUserProfile(long userId, UserProfile userProfile){

    setNewValue(currencyCode, new ProfileSetter(){
        apply(String newValue){
            Util.setCurrency(newValue);
        }
    });
    
    setNewValue(langCode, new ProfileSetter(){
        apply(String newValue){
            Util.setLang(newValue);
        }
    });
}

private void setNewValue(String newValue, ProfileSetter f){
    if (newValue != null && newValue.trim().length() > 0)
        f.apply(newValue);
}

interface ProfileSetter{
    apply(String newValue);
}


That's all.

27 March 2013

Go functional the Java way (1)

Functional programming deals with functions as a High-order functions that can be used the same way the variables are used, so as the functions can by send as a parameters to other functions.

In Java, we can achieve this by sending an interface containing this simple function to some method.

If we have a function "sum" that looks like:

public static int sum(int[] arr) {
    int sum = 0;
    for (int i=0; i < arr.length; i++) {
            sum += arr[i];
    }
    return sum;
}

And we need to sum the array based on some condition, If Java supports passing functions to method, we could pass the function this way:

sum(new int[]{1, 2, 3, 4, 5}, function(int i){ return i%2 ==0 } )

But since Java doesn't, We should go the Java way doing that, notice the example below:


public class Main {
    public static void main(String[] args) {
        
        int sum = sum(new int[] {1, 2, 3, 4, 5}, new Predicate<Integer>() {
            public boolean test(Integer t) {
                return t >= 4 ;
            }
        });
        System.out.println(sum);
    }
    
    public static int sum(int[] arr, Predicate<Integer> accept) {
        int sum = 0;
        for (int i=0; i < arr.length; i++) {
            if (accept.test(arr[i]))
                sum += arr[i];
        }
        return sum;
    }
    
    interface Predicate<T>{
        boolean test(T t);
    }
}


Does the above code looks familiar?
It should, since the Collections.sort uses similar code to do custom sorting of a List.

In Java8 and according to http://www.dzone.com/links/r/why_we_need_lambda_expressions_in_java_part_1.html the syntax should be much simpler using lambda expression. It might look like Scala code:


sum(new int[]{1, 2, 3, 4, 5}, (Intger i) => i%2 == 0 )


Reference and code blocks from the above link.