<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
Ooh, that's decidedly nasty. I suppose I should have read the docs
of the primop before drawing conclusions, but then, being lazy is
part of the deal here... ;)<br>
<br>
Thanks for the explanation!<br>
<br>
- Tom<br>
<br>
<div class="moz-cite-prefix">On 10/03/2023 15:05, David Feuer wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CAMgWh9v7gaDmqJ+MaU3=qR-C5OoU7z7bP-3ju3TF7niXuku2aw@mail.gmail.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<div dir="auto">
<div>Unfortunately not. The type the type checker is told for
the `atomicModifyMutVar2#` primop is a lie (too permissive).
The type documented in its Haddocks is also a lie (too
restrictive). Its most precise type, as I understand it, is
(translating away the unboxed stuff and the internal I/O
representation)
<div dir="auto"><br>
</div>
<div dir="auto">atomicModifyMutVar2</div>
<div dir="auto"> :: IORef a<br>
</div>
<div dir="auto"> -> (a -> t)</div>
<div dir="auto"> -> IO (a, t)</div>
<div dir="auto">-- with the condition that `t` is a record
whose first field that is represented by a pointer (what we
call BoxedRep) has a type with the same memory
representation as `a`.</div>
<div dir="auto"><br>
</div>
<div dir="auto">While it would be possible to express that
fairly precisely using the Generics approach, I think it's
too hard to think about "the first pointer field", and the
"same memory representation" bit mucks with type inference.
So I restricted it a little to "the first field, which must
be a pointer", and "with type `a`".</div>
<div dir="auto"><br>
</div>
<div dir="auto">There's a sort of "hidden unsafeCoerce" in the
primop call, where we know that the "selector thunk" it
builds (a thunk applying a record selector, in this case
fst) will extract the field we want out of what we give it.
The type checker is clueless and just accepts whatever.</div>
<br>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Fri, Mar 10, 2023, 4:09
AM Tom Smeding <<a href="mailto:x@tomsmeding.com"
moz-do-not-send="true" class="moz-txt-link-freetext">x@tomsmeding.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div> I'm not the person to ask :) Maybe someone else on
the list can chip in here.<br>
<br>
Another question if you don't mind (I'm learning here):
you say below that in <a
id="m_-4214265619866510319v:atomicModifyIORef2Native"
rel="noreferrer" moz-do-not-send="true">atomicModifyIORef2Native,</a>
you rely on heap object layout to unsafeCoerce between a
pair and any object with an interesting value in the
first field. But looking at the source [1], it seems you
only do this for base < 4.13, i.e. GHC < 8.8.4.
That's been a while.<br>
<br>
Is it true that for GHCs since 8.8.4 you can just use a
primop to do what you want directly, without the magic
Generic stuff? If so, perhaps you can even drop the
Generic constraints for high enough GHC versions (by
extending the scope of the CPP slightly)? 8.6.5 is still
popular, but simultaneously a whole bunch of
applications don't care about GHCs <9 anymore.<br>
<br>
- Tom<br>
<br>
[1]:
<a
href="https://hackage.haskell.org/package/atomic-modify-general-0.1.0.0/docs/src/Data.IORef.AtomicModify.Generic.html#atomicModifyIORef2Native"
target="_blank" rel="noreferrer"
moz-do-not-send="true" class="moz-txt-link-freetext">https://hackage.haskell.org/package/atomic-modify-general-0.1.0.0/docs/src/Data.IORef.AtomicModify.Generic.html#atomicModifyIORef2Native</a><br>
<br>
<div>On 10/03/2023 09:45, David Feuer wrote:<br>
</div>
<blockquote type="cite">
<div dir="auto">Whoops! Thanks for pointing that out.
I'll fix it and push new docs. There's not much
magic in that part of the code itself; the nasty
magic is knowing that the first pointer in any
record is in the same position in its heap object as
the first component of a pair. Speaking of which, do
you have any idea if it'll work for non-record types
whose constructors all have the same first field?
I'm guessing yes, but I haven't experimented yet.</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Fri, Mar 10,
2023, 3:27 AM Tom Smeding <<a
href="mailto:x@tomsmeding.com" target="_blank"
rel="noreferrer" moz-do-not-send="true"
class="moz-txt-link-freetext">x@tomsmeding.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">Hi
David,<br>
<br>
Fancy stuffs!<br>
<br>
Wondering how much magic was going on in
implementing this, I saw that <br>
atomicModifyIORef2Native misses the haddock marker
'|' in the source; <br>
thus your extensive doc comment doesn't show up on
hackage.<br>
<br>
Cheers,<br>
Tom<br>
<br>
On 10/03/2023 03:01, David Feuer wrote:<br>
> I just put together a new package,
atomic-modify-general, for<br>
> generalizations of the `atomicModifyIORef`
operation. In particular:<br>
><br>
> 1. Versions that allow a result of an
arbitrary type (not necessarily<br>
> a pair), where the caller passes in an
extraction function. These work<br>
> with `Array` and `SmallArray` from
`primitive` as well as `IORef`.<br>
> 2. A version that works with record types
(not just pairs) whose first<br>
> field is the new value to install in the
`IORef`. This uses<br>
> implementation details of the
`atomicModifyMutVar#` primop as well as<br>
> GHC's heap object layout to achieve better
performance.<br>
><br>
> Please try it out and let me know how it
goes, and what extras you may want!<br>
><br>
> Hackage: <a
href="https://hackage.haskell.org/package/atomic-modify-general-0.1.0.0"
rel="noreferrer noreferrer noreferrer"
target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">https://hackage.haskell.org/package/atomic-modify-general-0.1.0.0</a><br>
>
_______________________________________________<br>
> Haskell-Cafe mailing list<br>
> To (un)subscribe, modify options or view
archives go to:<br>
> <a
href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe"
rel="noreferrer noreferrer noreferrer"
target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
> Only members subscribed via the mailman list
are allowed to post.<br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives
go to:<br>
<a
href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe"
rel="noreferrer noreferrer noreferrer"
target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are
allowed to post.</blockquote>
</div>
</blockquote>
<br>
</div>
</blockquote>
</div>
</div>
</div>
</blockquote>
<br>
</body>
</html>