Saturday, July 25, 2015

Java 8 Streams


Introduction

Every application create and process collections. In Java until recently if you want to do some "finding" or "grouping" on collections you must code it yourself. It was not very exciting and it is repetitive job in nature. groovy for example offers great tools for transforming and managing collection. Check this link for some great examples. Java 8 borrows some concepts from groovy, but also go one step forward with multi core processing and stream concepts.

In SQL you don't need to implement how to calculate grouping or something else, you just describe your expectation (what you want to have).  Stream API in Java 8 is guided with same philosophy.

What is stream?

Stream is basically a sequence of elements from a source that supports aggregate operations. Let's break this statement:
  • Sequence of elements: Stream provides an interface to a sequenced set of values. Implementation of this interface don't store values, values are calculated on run-time.
  • Source: This is where are values are stored. Collection, arrays, I/O.
  • Aggregate operations: All common SQL-like (group, count, sum) and function programming languages constructions (filter, map, reduce, find, match, sorted).
Streams also have to fundamental characteristics:
  • Pipelining: This allows operation on stream to be chained into large pipeline. 
  • Internal iteration: Collections are iterated externally (explicit iteration), stream do the iteration behind the scenes.
Streams are not collections! In a nutshell, collections are about data and streams are about computations. The difference between collections and streams has to do with when things are computed. Every element in the collection has to be computed before it can be added to the collection. In contrast, a stream is a conceptually fixed data structure in which elements are computed on demand. For example in following example no work is actually done until collect is invoked:
List numbers = Arrays.asList(1, 4, 1, 4, 2, 8, 5);
List distinct = numbers.stream().map( i -> i*i).
      distinct().collect(Collectors.toList());
System.out.printf("integers: %s, squares : %s %n", numbers, distinct);
There are two types of stream operations:
  • Intermediate: can be connected together because their return type is a Stream.
  • Terminal: this kind of operation produce a result from a pipeline such as a List, an Integer, or even void (any non-Stream type).
Intermediate operations do not perform any processing until a terminal operation is invoked on the stream pipeline; they are “lazy.”

Streams also use short-circuiting where we need to process only part of the stream, not all of it, to return a result. This is similar to evaluating a large Boolean expression chained with the and operator.

This was just high level overview W/O detailed examples of stream API. It is easy to find examples on other sources like here. In my opinion Stream API is great and refreshing new feature in Java 8, especially with it's lazy, short-circuit multi core features.

Tuesday, July 21, 2015

JavaScript Promises

What are promises?

 

Promises quickly become standard way we handle asynchronous operations in JavaScript. Everybody who code even little bit in JavaScript is familiar with callbacks. Essence of using callback functions in JavaScript passing a function as an argument in another function and later execute that passed-in function or even return it to be executed later.
There are several problems with callback. For example when you need to be sure that two callbacks finishes before you do something, you must introduce new variables to track state of each callback. Callbacks also lead to another problem, which you should be already familiar with: callback hell.

Callback hell

 

I think this all started with node.js and callback hell get a bad rap from the node.js community. This is because when you have your node application with express and mongoose then callbacks are all over the place.
When you need to perform number of actions in specific sequence in JavaScript,  you must use nested functions. Something like this:
asyncCall(function(err, data1){
    if(err) return callback(err);       
    anotherAsyncCall(function(err2, data2){
        if(err2) return calllback(err2);
        oneMoreAsyncCall(function(err3, data3){
            if(err3) return callback(err3);
            // are we done yet?
        });
    });
});
You can use promises to make this code prettier:
asyncCall()
.then(function(data1){
    // do something...
    return anotherAsyncCall();
})
.then(function(data2){
    // do something...  
    return oneMoreAsyncCall();    
})
.then(function(data3){
   // the third and final async response
})
.fail(function(err) {
   // handle any error resulting from any of the above calls    
})
.done();
Lot nicer isn't it?
You can see that instead of requiring a callback we are returning a Promise object. You can chain promises, so subsequent then() calls on the Promise object also return promises.
We don't need to check for error in every callback, but only at the end of promise chain. This is also feature of promises.

Promises are not only solution to callback hell. Some times callback hell is direct consequence of poor code organization. In some cases promises only hide underlying structural problems of code. I mean it you need 5 indention you're screwed anyway, and should fix your program. You can find here some of the hints how to resolve callback hell

Implementation 

 

Promises have arrived natively in JavaScript, but for the end I want to provide half baked promise implementation with comments, so you have feeling how promises are (could be) impelmented:
function Promise(fn) {
  var state = 'pending';
  var value;
  var deferred;
  
  //When function we passed is done, this will be called.
  //If then is called before resolve, then value for then is deffered to function outside promise.
  //If then is called after resolve, then value is readed from internal state.
  function resolve(newValue) {
    value = newValue;
    state = 'resolved';
    
    if(deferred) {
      handle(deferred);
    }
  }

  function handle(onResolved) {
    if(state === 'pending') {
      deferred = onResolved;
      return;
    }

    onResolved(value);
  }
  
  //This will be invoced when client calls it.
  this.then = function(onResolved) {
    handle(onResolved);
  };

  //Executing function that was passed into promise.
  //We are waithing until this function is finished.
  fn(resolve);
}

function testPromise() {
    return new Promise(function(resolve) {
        var value = readFromDatabase();
        resolve(value);
    });
}

testPromise().then(function(databaseValue) {
    log(databaseValue);
});