[Haskell-cafe] ANN: Future 1.1.0 concurrency library

ChrisK haskell at list.mightyreason.com
Mon Mar 9 16:54:06 EDT 2009


   As a side effect of the discussion of the new C++ future/promise features at 
http://lambda-the-ultimate.org/node/3221 I have implemented a Haskell package 
called "future" at


This ought to do what C++ standard futures/promises do, plus a bit more.  The 
main operation is

 > forkPromise :: IO a -> IO (Promise a)

This sets the "IO a" operation running in a fresh thread.  The eventual result 
can be accessed in many ways (non-blocking, blocking, blocking with timeout).

 > let one :: Int; one = 1
 > p <- forkPromise (return (one+one))
 > x <- get
 > y <- wait

x is an Int with value 2.
y is an (Either SomeException Int) with value (Right 2).

The useful thing about futures, as opposed to various IVar packages, is handling 
  the case where the forked operation ends with an exception.  The exception 
becomes the return value of the promise.  The "get" operation rethrows it, the 
"wait" operation returns it as (Left ...).

There is also an "abort" command to kill a promise.  The dead promise may then 
have an exceptions as its value.

The "plus a bit more" than C++ is the nonblocking "addTodo" feature.  This takes 
a continuation function from the "Either SomeException a" to an IO operation. 
These continuation functions get queued and they are run immediately after the 
the forked operation completes.  Once completed any new "addTodo" continuations 
run immediately.

These continuations allow you to race a list of action and take the first one 
done, or to collect the answers as they complete into a Chan.  Both of those 
options are demonstrated in Future.hs as racePromises and forkPromises.

It should be safe to use "unsafePerformIO . get" or "unsafePeformIO . wait" to 
get lazy access to the result, which is itself immutable once set.


More information about the Haskell-Cafe mailing list