Simon Marlow wrote:
Simon Marlow wrote:
[...] There was this, from Dean Herrington:
http://haskell.cs.yale.edu/pipermail/ffi/2002-October/000940.html
I don't have any strong feelings (I rarely do, where names are concerned).
I would be happy with his proposal. We can leave the IORef stuff in IOExts as it is and use the new signatures and functions in Data.IORef. The only annoying thing is the signature of Data.IORef.modifyIORef, but we could declare the old signature as a bug... :-]
Actually, looking at the proposal again, I don't think I like the changes to the MVar interface. atomicModifyMVar seems strange, because modifyMVar is already atomic. We have to be careful about trying to smooth over differences between IORef and MVar where those differences are real and important.
The current `modifyMVar`, though "exception safe", is not "atomic" in the same way that the proposed `atomicModifyMVar` would be. Unless I misunderstand, during the execution of `modifyMVar`'s second argument, the mvar is empty and could be filled by some other thread. With `atomicModifyMVar`, the contents of the mvar are changed atomically, based on the given (pure) function; no other thread can intervene. The difference described above is noticeable in the implementation of `readMVar` and `swapMVar`. As currently implemented, these functions are not atomic as one might expect. They would better be implemented in terms of `atomicModifyMVar`. Thinking about `readMVar` and `swapMVar` reminds me that `tryReadMVar` and `trySwapMVar` are missing from the interface. Thinking about the "try" and "atomic" variants suggests that we ought also to add: atomicTryModifyMVar :: MVar a -> (a -> (a, b)) -> IO (Maybe b) atomicTryModifyMVar_ :: MVar a -> (a -> a) -> IO Bool with semantics that I think are obvious.
I don't mind changing modifyIORef to have a signature which is more similar to modifyMVar, and I think adding atomicModifyIORef_ is a good idea (although it needs a new primitive if we're to take advantage of its efficiency over atomicModifyIORef). Summary:
- make modifyIORef's type match modifyMVar - add modifyIORef_ - add atomicModifyIORef and atomicModifyIORef_
One might reasonably worry about the proliferation of MVar manipulation functions. I think it's useful to realize that there are semantically only four primitives in the proposed extended interface: `newEmptyMVar`, `atomicModifyMVar`, `atomicTryModifyMVar`, and `addMVarFinalizer`. All the other functions can be built simply out of these primitives. In fact, I would recommend we include in the documentation for all the nonprimitive functions their definitions in terms of the primitives. -- Dean