Search code examples
scalaasynchronousconcurrencyscalazscalaz7

A little help on understanding Scalaz Future and Task


I'm trying to understand the idea and purpose behind scalaz concurrent package, primarily Future and Task classes, but when using them in some application, it's now far from simple sequential analog, whereas scala.concurrent.Future, works more then better. Can any one share with his experience on writing concurrent/asynchronous application with scalaz, basically how to use it's async method correctly? As i understand from the sources async doesn't use a separate thread like the call to standard future, or fork/apply methods from scalaz works, so why it is called async then? Does it mean that in order to get real concurrency with scalaz i always have to call fork(now(...)) or apply?


Solution

  • I'm not a scalaz expert, but I'll try to help you a little bit. Let me try answer your questions one by one:

    1) Can any one share with his experience on writing concurrent/asynchronous application with scalaz, basically how to use it's async method correctly?

    Let's first take a look at async signature:

    def async[A](listen: (A => Unit) => Unit): Future[A]

    This could be a bit cryptic at first, so as always it's good idea to look at tests to understands possible use cases. In https://github.com/scalaz/scalaz/blob/scalaz-seven/tests/src/test/scala/scalaz/concurrent/FutureTest.scala you can find the following code:

    "when constructed from Future.async" ! prop{(n: Int) =>
      def callback(call: Int => Unit): Unit = call(n)
      Future.async(callback).run must_==   
    }
    

    As we know from signature Future.async just construct new Future using function of signature (A => Unit) => Unit. What this really means is that Future.async takes as parameter function which for given callback makes all required computations and pass the result to that callback.
    What is important to note it that Future.async does not run any computations on itself, it only prepare structure to run them later.

    2) As i understand from the sources async doesn't use a separate thread like the call to standard future, or fork/apply methods from scalaz works, so why it is called async then?

    You are correct. Only fork and apply seems to be running anything using threads, which is easy to notice looking at the signatures which contains implicit pool: ExecutorService. I cannot speak for the authors here, but I guess async is related to the callback. It means that rather than blocking on Future to get it result at the end you will use asynchronous callback.

    3) Does it mean that in order to get real concurrency with scalaz i always have to call fork(now(...)) or apply?

    From what I can say, yes. Just notice that when you are creating Future using syntax Future(x) you are using apply method here, so this is kind of default behavior (which is fine).

    If you want to better understand design of Scalaz Futures I can recommend you reading "Functional Programming in Scala". I believe this book is written by main Scalaz contributors and chapter 7 discusses designing API for purely functional parallelism library. It's not exactly the same as Scalaz Future, but you can see many similarities.