ANN: Future 1.1.0 concurrency library

Hello, 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 http://hackage.haskell.org/cgi-bin/hackage-scripts/package/future 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. Cheers, Chris

This is way cool!
/jve
On Mon, Mar 9, 2009 at 4:54 PM, ChrisK
Hello,
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
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/future
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.
Cheers, Chris
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

I'd also like to point out that Chris did this with 165 lines of
code--including comments and whitespace! If you drop the whitespace and
comments, it's only 91 lines!
/jve
On Mon, Mar 9, 2009 at 4:54 PM, ChrisK
Hello,
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
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/future
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.
Cheers, Chris
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Don Stewart wrote:
Who needs to build futures into the language -- all you need is MVars, eh?
For a pure computation in Haskell one can use "par" (which did take changing the runtime, and arguably adding to the language). The future package I uploaded is just a clean way to get something a little like "par" for an IO computation, as a library. One can build many useful APIs quite cheaply using MVars. Hackage even has a few examples (many under the Concurrency heading). This API was interesting solely because it is in the C++ standard and the discussion about how the standard left out useful proposed parts of the API. Cheers, Chris
participants (3)
-
ChrisK
-
Don Stewart
-
John Van Enk