Proposal: Add atomic IORef operations to Data.IORef

David Feuer david.feuer at
Fri Jan 15 20:29:37 UTC 2021

I disagree. I believe we should offer both atomicModifyIORef2 and an
atomicModifyIORef2'. The latter should force the new value in the
IORef but, unlike atomicModifyIORef', should not force the returned
value. Or if you and others prefer, we could offer a strict
atomicModifyIORef and a lazy atomicModifyIORef2Lazy. As a Haskell
programmer, I really don't want totally polymorphic values getting
forced behind my back. It's actually possible to write an even lazier
version that doesn't even force the function result pair, but I don't
think that's a very useful idea.

One other thing: the natural approach to atomicModifyIORef2' uses a
"half-strict pair" type

    data HSPair a b = HSPair !a b
    atomicModifyIORef2' :: IORef a -> (a -> HSPair a b) -> IO (a, HSPair a b)

I don't know to what extent users are willing to tolerate such an
extra datatype.

Side note: the peculiarly strict behavior of atomicModifyIORef' is a
result of the poor design of the old atomicModifyMutVar# primop.

On Fri, Jan 15, 2021 at 3:19 PM Alexey Kuleshevich <alexey at> wrote:
> Both of these functions are lazy with respect to the new value being written into the IORef, which is a horrible default for atomic operations. That is why atomicModifyIORef is a source of memory leaks and terrible performance, which is also why atomicModifyIORef' is almost always used instead.
> So +1 from me on adding strict versions of these functions that force new value to whnf, but -1 for adding these lazy versions as they are currently defined in GHC.IORef
> Alexey.
> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
> On Friday, January 15, 2021 11:05 PM, David Feuer <david.feuer at> wrote:
> > GHC.IORef currently exports
> >
> > atomicModifyIORef2 :: IORef a -> (a -> (a,b)) -> IO (a, (a, b))
> > atomicSwapIORef :: IORef a -> a -> IO a
> >
> > atomicModifyIORef2 is a lot like atomicModifyIORef, but it returns
> > both the old value in the IORef and the full result of applying the
> > user-supplied function to that. This is a pretty thin wrapper around
> > the newish atomicModifyMutVar2# primop, which has replaced the less
> > powerful atomicModifyMutVar#.
> >
> > atomicSwapIORef atomically installs a user-supplied value in an IORef
> > and returns the old value. It is currently implemented using
> > atomicModifyIORef2, but it can and should be reimplemented using its
> > own, more efficient primop.
> >
> > I propose to add both of these functions to Data.IORef.
> >
> > David
> >
> > Libraries mailing list
> > Libraries at
> >

More information about the Libraries mailing list