<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p>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.<br>
</p>
<p>As for tuples more than pairs, they're not really needed, user
can always squeeze their product into `b` component. <br>
</p>
<p>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.</p>
<br>
<div class="moz-cite-prefix">On 2018年07月08日 03:09, David Feuer
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CAMgWh9ucRiUmfJYPVueTVgJDG_Sr4qaaE=eR87U6aLpZGZVeTA@mail.gmail.com">
<div dir="auto">Whoops! I left out the proposal link:
<div dir="auto"><br>
</div>
<div dir="auto"><a
href="https://github.com/ghc-proposals/ghc-proposals/pull/149"
moz-do-not-send="true">https://github.com/ghc-proposals/ghc-proposals/pull/149</a><br>
</div>
<div dir="auto"><br>
</div>
<div dir="auto">Also, what I called atomicModifyIORef_ below
should really be called something like <span
style="font-family:sans-serif">atomicModifyIORef'_, since it
forces a polymorphic value.</span></div>
<div dir="auto"><span style="font-family:sans-serif"><br>
</span></div>
<div dir="auto"><span style="font-family:sans-serif">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:</span></div>
<div dir="auto"><span style="font-family:sans-serif"><br>
</span></div>
<div dir="auto"><span style="font-family:sans-serif">atomicModifyIORefSoloLazy</span></div>
<div dir="auto"><span style="font-family:sans-serif"> :: IORef
a -> (a -> Solo a) -> IO (Solo a)</span></div>
<div dir="auto"><span style="font-family:sans-serif"><br>
</span></div>
<div dir="auto">
<div dir="auto" style="font-family:sans-serif">atomicModifyIORefSolo</div>
<div dir="auto" style="font-family:sans-serif"> :: IORef a
-> (a -> Solo a) -> IO a</div>
<div dir="auto" style="font-family:sans-serif"><br>
</div>
<div dir="auto" style="font-family:sans-serif">
<div dir="auto">atomicModifyIORef3, atomicModifyIORef3Lazy</div>
<div dir="auto"> :: IORef a -> (a -> (a, b, c)) ->
IO (a, b, c)</div>
<div dir="auto"><br>
</div>
<div dir="auto">etc.</div>
<div dir="auto"><br>
</div>
<div dir="auto">Should we add any such?</div>
</div>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr">On Sat, Jul 7, 2018, 2:35 PM David Feuer <<a
href="mailto:david.feuer@gmail.com" moz-do-not-send="true">david.feuer@gmail.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="auto">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.
<div dir="auto"><br>
</div>
<div dir="auto">The new primops lead naturally to several
thin wrappers:</div>
<div dir="auto"><br>
</div>
<div dir="auto">-- Atomically replace the IORef contents</div>
<div dir="auto">-- with the first component of the result of</div>
<div dir="auto">-- applying the function to the old
contents.</div>
<div dir="auto">-- Return the old value and the result of</div>
<div dir="auto">-- applying the function, without forcing
the latter.</div>
<div dir="auto">--</div>
<div dir="auto">-- atomicModifyIORef ref f = do</div>
<div dir="auto">-- (_old, ~(_new, res)) <-
atomicModifyIORef2Lazy ref f</div>
<div dir="auto">-- return res</div>
<div dir="auto">atomicModifyIORef2Lazy</div>
<div dir="auto"> :: IORef a -> (a -> (a, b)) -> IO
(a, (a, b))</div>
<div dir="auto"><br>
</div>
<div dir="auto">-- Atomically replace the IORef contents</div>
<div dir="auto">-- with the result of applying the function</div>
<div dir="auto">-- to the old contents. Return the old and</div>
<div dir="auto">-- new contents without forcing the latter.</div>
<div dir="auto">atomicModifyIORefLazy_</div>
<div dir="auto"> :: IORef a -> (a -> a) -> IO (a,
a)</div>
<div dir="auto"><br>
</div>
<div dir="auto">-- Atomically replace the IORef contents</div>
<div dir="auto">-- with the given value and return the old</div>
<div dir="auto">-- contents.</div>
<div dir="auto">--</div>
<div dir="auto">-- atomicWriteIORef ref x = void
(atomicSwapIORef ref x)</div>
<div dir="auto">atomicSwapIORef</div>
<div dir="auto"> :: IORef a -> a -> IO a</div>
<div dir="auto"><br>
</div>
<div dir="auto">Based on the code I've read that uses
atomicModifyIORef, I believe that the complete laziness
of <span style="font-family:sans-serif">atomicModifyIORef2Lazy</span> and <span
style="font-family:sans-serif">atomicModifyIORefLazy_</span> is
very rarely desirable. I therefore believe we should also
(or perhaps instead?) offer stricter versions:</div>
<div dir="auto"><br>
</div>
<div dir="auto">
<div dir="auto" style="font-family:sans-serif">atomicModifyIORef2</div>
<div dir="auto" style="font-family:sans-serif"> :: IORef
a -> (a -> (a, b)) -> IO (a, (a, b))</div>
<div dir="auto" style="font-family:sans-serif">atomicModifyIORef2
ref f = do</div>
<div dir="auto" style="font-family:sans-serif"> r@(_old,
(_new, _res)) <- atomicModifyIORef2Lazy ref f</div>
<div dir="auto" style="font-family:sans-serif"> return r</div>
<div dir="auto" style="font-family:sans-serif"><br>
</div>
<div dir="auto" style="font-family:sans-serif">
<div dir="auto">atomicModifyIORef_</div>
<div dir="auto"> :: IORef a -> (a -> a) -> IO
(a, a)</div>
<div dir="auto">atomicModifyIORef_ ref f = do</div>
<div dir="auto"> r@(_old, !_new) <-
atomicModifyIORefLazy_ ref f</div>
<div dir="auto"> return r</div>
<div dir="auto"><br>
</div>
<div dir="auto">The classic atomicModifyIORef also
admits a less gratuitously lazy version:</div>
<div dir="auto"><br>
</div>
<div dir="auto">atomicModifyIORefNGL</div>
<div dir="auto"> :: IORef a -> (a -> (a,b)) ->
IO b</div>
<div dir="auto">atomicModifyIORefNGL ref f = do</div>
<div dir="auto"> (_old, (_new, res)) <-
atomicModifyIORef2 ref f</div>
<div dir="auto"> return res</div>
<div dir="auto"><br>
</div>
<div dir="auto">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.</div>
</div>
</div>
</div>
</blockquote>
</div>
<!--'"--><br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
Libraries mailing list
<a class="moz-txt-link-abbreviated" href="mailto:Libraries@haskell.org">Libraries@haskell.org</a>
<a class="moz-txt-link-freetext" href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a>
</pre>
</blockquote>
<br>
</body>
</html>