Wednesday, September 11, 2013

Dart's 'Future'

Overall, Dart language is very powerful and the language nature is very familiar to me as long time functional language advocates.(actually mixture of functional and object oriented).

Essentially it is very powerful to abstract procedure.
Often other none functional programming languages are very weak at abstracting procedure.
Since refactoring common process can not be done easily, and it ends up writing repetitive procedure again and again.
Because of this, Dart program are tend to become very short compared to corresponding code in Java.
short, concise, abstract code is the trait of functional programming.(Thus the title of this blog, 'Zen')


Shortness is just one aspect of it, but more important aspect is to change the way to think of problem.
Also functional style will clarify the basic aspect of asynchronous programs.

the Future class of Dart is in this respect very important.
The basic  idea is to allow to write a sequential steps of asynchronous call  in sequential way.
implicitly Future is hiding some event based trigger mechanism inside the class, because of that, the code using Future looks just a sequence of functions.

Future<A> fu = f();
fu
.then((A a)=>b())
..then((B b1)=>c())
...
.then((e){...})
.then.((i)=>i);

These 'then' method (of Future class) creates another Future(of different parametric type determined by the return type of the function passed to the then method).
So essentially with 'then' future takes a function and create another future .
this is asynchronous version of function combination function from two function.

fun then('X->'Y f, 'Y-'Z g): 'X->'Z =>('X x)=>g(f(x)); // pseudo code
Although Dart does not have this kind of type scheme(see ML)) or generic type specification, but it is achieving similar things.

but in case of Future, it is not ordinarily sequence of function calls, but it determines the sequence of function calls triggered by internal events.
if all functions in the parameter are written without asynchronous call, these functions are invoked immediately in a cascade way. One after another function call, the return value is used to trigger next future.
But if there is a asynchronous call in the function body, then we can control the  triggering timing using completer.
Future<A> fu = f();
fu
.then((A a)=>{
  Completer<B> c = new Completer<B>();
  B b = new  B();
...
  stream.open(..., onDone: {
     c.complete(b); // this allows to controls when the next function(f1) is to be triggered.
  });
  return c.future; // the action must return a future which is triggered by the complete invocation above.
  }
)
..then(f1);

No comments:

Post a Comment