Proposal: Control.Concurrent.Async

Chris Kuklewicz haskell at
Sat Jun 9 10:50:27 CEST 2012

Your superset API is excellent.  I have one important suggestions: non-blocking

By default, when your combinators like 'withAsync' and 'concurrently' use
'cancel' or 'killThread' they should use it in a non-blocking way.  The exported
'cancel' & 'cancelWith' should be unchanged and their documention should note
that they are blocking.

Consider 'concurrently'.  Perhaps there need to to be two 'concurrently'
versions?  One is blocking-killThread and guarantees that both are done or dead
when it returns and the other is non-blocking-killThread and returns ASAP.
Neither can be turned into the other by the user.

Rather than API duplication the 'concurrently' operation could get a new
parameter that selects blocking vs non-blocking killThread.

Hmmm.... the root problem is some Async tasks that, probably due to foreign
calls, are uninterpretable.  Maybe the user could label which Async tasks must
be killed blocking or non-blocking.  The default is non-blocking to avoid
infecting other threads with uninterpretable calls.  When the user needs the
extra property of guaranteed kills the user can change the label.  I have no
immediate idea whether a mutable or immutable label would be better.


On 2012/06/08 09:37, Simon Marlow wrote:
> I'd like to add a higher-level concurrency API to the base package. This API has
> grown while I've been working on examples for my book, and I'm convinced that we
> should have something like this in the standard libraries.  Here's the API I
> propose:
> In fact it already exists in at least two packages on Hackage: 'async' and
> 'threads'.  My version is a superset of both of these, except for a few small
> differences (which are up for discussion, of course).
> One good reason to have this package is that it avoids some common pitfalls,
> such as forgetting to handle exceptions in your child threads.  In the Async
> API, you get to choose whether to (a) receive the result as 'Either
> SomeException a', or (b) have the exception re-thrown in the waiting thread. 
> You don't get to ignore it altogether.
> Another common pitfall avoided by this library is accidentally leaving threads
> running in the background.  This is handled by withAsync:
>   withAsync :: IO a -> (Async a -> IO b) -> IO b
> the child thread is always cancelled (i.e. killed) when the second argument
> returns or throws an exception, if it hasn't finished already.
> I'm opening this up for discussion so that we can tidy up any inconsistent
> details and add any functions that people feel are missing.  Naming is obviously
> up for discussion too.
> Cheers,
>     Simon
> _______________________________________________
> Libraries mailing list
> Libraries at

More information about the Libraries mailing list