[Haskell-cafe] Can you do everything without shared-memory concurrency?

Ryan Ingram ryani.spam at gmail.com
Wed Sep 10 14:28:43 EDT 2008

On Wed, Sep 10, 2008 at 2:55 AM, Maarten Hazewinkel
<maarten.hazewinkel at gmail.com> wrote:
> And a further note on sharing memory via a transactional resource (be it
> STM, a database or a single controlling thread).
> This situation always introduces the possibility that your update fails, and
> a lot of client code is not designed to deal with that. The most common
> pattern I see in database access code is to log the exception and continue
> as if nothing happened. The proper error handling only gets added in after a
> major screwup in production happens, and the usually only the the particular
> part of the code where it went wrong this time.

This seems to be a bit too much F.U.D. for STM.  As long as you avoid
unsafeIOToSTM (which you really should; that function is far more evil
than unsafePerformIO), the only failure case for current Haskell STM
is starvation; some thread will always be making progress and you do
not have to explicitly handle failure.

This is absolutely guaranteed by the semantics of STM: no effects are
visible from a retrying transaction--it just runs again from the
start.  You don't have to write "proper error handling" code for
transactional updates failing.

The only reason why this isn't possible in most database code is that
access to the database is happening concurrently with side effects to
the local program state based on what is read from the database.
Removing the ability to have side effects at that point is what makes
STM great.  It's easy to make side effects happen on commit, though,
just return an IO action that you execute after the atomically block:

> atomicallyWithCommitAction :: STM (IO a) -> IO a
> atomicallyWithCommitAction stm = join (atomically stm)

  -- ryan

More information about the Haskell-Cafe mailing list