Proposed addition to stm: atomicallyIO and afterCommit
Simon Marlow
marlowsd at gmail.com
Wed Feb 24 04:58:40 EST 2010
John Lauchbury has proposed the following addition to
Control.Concurrent.STM. John's proposal is below, comments welcome.
Personally I'm in two minds about this. It certainly captures a useful
idiom, but it fails the "don't name compositions" test, and one of the
additions is just a renaming of 'return', which makes it hard to justify.
Cheers,
Simon
-----
I find I often write STM code with the structure:
do
... IO code ...
v <- atomically $ do
... STM code ...
if .....
then do
... STM code ...
return (Left ...)
else do
... STM code ...
return (Right ...)
case v of
Left ... -> ... IO actions ...
Right ... -> ... IO actions ...
where I have to communicate the result of choices inside STM code to
corresponding code in the outer IO monad. This means that two separate
parts of the code have to be kept in sync. In this simple case it's
merely irritating. With larger and more complex structures it can be
quite tricky to keep right.
Now I use the functions 'atomicallyIO' and 'afterCommit', and can
structure the code as
do
... IO code ...
v <- atomicallyIO $ do
... STM code ...
if .....
then do
... STM code ...
afterCommit $ ... IO actions ...
else do
... STM code ...
afterCommit $ ... IO actions ...
As you see, it allows the IO code to be placed in the appropriate part
of the STM code, ready to be executed when that STM branch is committed.
Here's the code to would be added to the STM module:
----------------------------------------------------------------------
-- 'atomicallyIO' and 'afterCommit' are useful syntactic sugar for a
-- simple continuation paradigm. They allow IO code to be placed within
-- the same block of STM code in which control decisions are made
-- (avoiding the need to communicate those decisions with a data type
-- sent to a subsequent matching case).
atomicallyIO :: STM (IO a) -> IO a
atomicallyIO ioSTM = join $ atomically ioSTM
afterCommit :: IO a -> STM (IO a)
afterCommit mIO = return mIO
----------------------------------------------------------------------
Obviously the code is very simple, but I still find it useful to name
the paradigm, and to have the specific type declarations to catch errors.
More information about the Libraries
mailing list