On Wed, Jul 11, 2018, 11:32 PM winter <drkoster@qq.com> wrote:
OK then, here's some subtle things i want to shout out if you're going to make the change ; )

1. The proposed naming is just not great, how about these:

atomicExchangeIORef :: IORef a -> (a -> (a, b)) -> IO (a, (a, b))
atomicExchangeIORef' :: IORef a -> (a -> (a, b)) -> IO (a, (a, b))

atomicApplyIORef :: IORef a -> (a -> a) -> IO (a, a)
atomicApplyIORef :: IORef a -> (a -> a) -> IO (a, a)

It may not that great but it's more informative IMO.

I agree that my names aren't great, but I think yours are worse.


3. atomicExchangeIORef should not force the tuple, e.g. don't pattern match on the tuple result, instead let users choose to force or not. (May worth adding some document, I'd be happy to help)

I generally disagree. Being lazy in the tuple is pretty much an invitation to memory leaks. I think the lazy version should ideally also be available (it's what the new primop will provide, after all), but I don't think it should be the obvious thing for people to reach for.


4. atomicExchangeIORef' will not only force the tuple, but also force both `a` and `b` part to match atomicModifyIORef' 's semantics.

I don't see the need for this. Users can easily force exactly what they want using atomicModifyIORef2 (or if they really want, atomicModifyIORef2Lazy).


5. atomicApplyIORef(and atomicApplyIORef') deserve its own primop, since we can skip building selector thunks all together.

Yes, I've implemented that primop already, and it will be added. I'm still looking for an expert to help implement the simplest of the lot, atomicSwapMutVar#, as efficiently as possible.