Discussion: New atomic IORef functions

winter drkoster at qq.com
Sun Jul 8 07:36:06 UTC 2018


I believe new variations should always be motivated by use-case if 
there're too many choices, the lazy behavior of old `atomicModifyIORef` 
is justified by some cases the modifying functions are lazy in its 
argument, thus a lazy version could win by not forcing previous thunks, 
we'd want to keep its behavior as how it's documented.

As for tuples more than pairs, they're not really needed, user can 
always squeeze their product into `b` component.

IMHO only the addition of `atomicModifyIORef_` is sensible in the 
context of base, other APIs may go to package like primitives. But if 
you have a motivated use case with `atomicModifyIORef2`, etc. Please 
tell me.


On 2018年07月08日 03:09, David Feuer wrote:
> Whoops! I left out the proposal link:
>
> https://github.com/ghc-proposals/ghc-proposals/pull/149
>
> Also, what I called atomicModifyIORef_ below should really be called 
> something like atomicModifyIORef'_, since it forces a polymorphic value.
>
> Another thing to note: the underlying atomicModifyMutVar2# primop 
> actually supports more than just pairs. It can handle triples, solos, 
> and any other record types whose first components are lifted:
>
> atomicModifyIORefSoloLazy
>   :: IORef a -> (a -> Solo a) -> IO (Solo a)
>
> atomicModifyIORefSolo
>   :: IORef a -> (a -> Solo a) -> IO a
>
> atomicModifyIORef3, atomicModifyIORef3Lazy
>   :: IORef a -> (a -> (a, b, c)) -> IO (a, b, c)
>
> etc.
>
> Should we add any such?
>
> On Sat, Jul 7, 2018, 2:35 PM David Feuer <david.feuer at gmail.com 
> <mailto:david.feuer at gmail.com>> wrote:
>
>     I have proposed[1] the replacement of the atomicModifyMutVar#
>     primop, and the addition of two cheaper but less capable ones. It
>     seems likely that the proposal will succeed, but that the GHC
>     steering committee will leave the question of user interface
>     changes to the libraries list. I would like to open the discussion
>     here.
>
>     The new primops lead naturally to several thin wrappers:
>
>     -- Atomically replace the IORef contents
>     -- with the first component of the result of
>     -- applying the function to the old contents.
>     -- Return the old value and the result of
>     -- applying the function, without forcing the latter.
>     --
>     -- atomicModifyIORef ref f = do
>     --   (_old, ~(_new, res)) <- atomicModifyIORef2Lazy ref f
>     --   return res
>     atomicModifyIORef2Lazy
>       :: IORef a -> (a -> (a, b)) -> IO (a, (a, b))
>
>     -- Atomically replace the IORef contents
>     -- with the result of applying the function
>     -- to the old contents. Return the old and
>     -- new contents without forcing the latter.
>     atomicModifyIORefLazy_
>       :: IORef a -> (a -> a) -> IO (a, a)
>
>     -- Atomically replace the IORef contents
>     -- with the given value and return the old
>     -- contents.
>     --
>     -- atomicWriteIORef ref x = void (atomicSwapIORef ref x)
>     atomicSwapIORef
>       :: IORef a -> a -> IO a
>
>     Based on the code I've read that uses atomicModifyIORef, I believe
>     that the complete laziness of atomicModifyIORef2Lazy and
>     atomicModifyIORefLazy_ is very rarely desirable. I therefore
>     believe we should also (or perhaps instead?) offer stricter versions:
>
>     atomicModifyIORef2
>       :: IORef a -> (a -> (a, b)) -> IO (a, (a, b))
>     atomicModifyIORef2 ref f = do
>       r@(_old, (_new, _res)) <- atomicModifyIORef2Lazy ref f
>       return r
>
>     atomicModifyIORef_
>       :: IORef a -> (a -> a) -> IO (a, a)
>     atomicModifyIORef_ ref f = do
>       r@(_old, !_new) <- atomicModifyIORefLazy_ ref f
>       return r
>
>     The classic atomicModifyIORef also admits a less gratuitously lazy
>     version:
>
>     atomicModifyIORefNGL
>       :: IORef a -> (a -> (a,b)) -> IO b
>     atomicModifyIORefNGL ref f = do
>       (_old, (_new, res)) <- atomicModifyIORef2 ref f
>       return res
>
>     Should we add that as well (with a better name)? Should we even
>     consider *replacing* the current atomicModifyIORef with that
>     version? That could theoretically break existing code, but I
>     suspect it would do so very rarely. If we don't change the
>     existing atomicModifyIORef now, I think we should consider
>     deprecating it: it's very easy to accidentally use it too lazily.
>
>
>
> _______________________________________________
> Libraries mailing list
> Libraries at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/libraries/attachments/20180708/7f09c709/attachment.html>


More information about the Libraries mailing list