[Haskell-cafe] ANN: atomic-modify-general

David Feuer david.feuer at gmail.com
Fri Mar 10 14:48:32 UTC 2023


You're right that the type checker doesn't know that about the primop, but
it *is* known at type checking time, so my little package makes sure it's
not unpacked. It's's available in the Generic metadata as
DecidedStrictness, which will be 'DecidedUnpack for a field that is
actually unpacked, and that can be inspected by a type family or class
instance.

On Fri, Mar 10, 2023, 9:12 AM Brandon Allbery <allbery.b at gmail.com> wrote:

> I expect it also can't know if the first field got unpacked. (or will
> be unpacked? I think that hasn't happened at typechecking time)
>
> On Fri, Mar 10, 2023 at 9:06 AM David Feuer <david.feuer at gmail.com> wrote:
> >
> > 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)
> >
> > atomicModifyMutVar2
> >   :: IORef a
> >   -> (a -> t)
> >   -> IO (a, t)
> > -- 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`.
> >
> > 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`".
> >
> > 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.
> >
> >
> > On Fri, Mar 10, 2023, 4:09 AM Tom Smeding <x at tomsmeding.com> wrote:
> >>
> >> I'm not the person to ask :) Maybe someone else on the list can chip in
> here.
> >>
> >> Another question if you don't mind (I'm learning here): you say below
> that in atomicModifyIORef2Native, 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.
> >>
> >> 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.
> >>
> >> - Tom
> >>
> >> [1]:
> https://hackage.haskell.org/package/atomic-modify-general-0.1.0.0/docs/src/Data.IORef.AtomicModify.Generic.html#atomicModifyIORef2Native
> >>
> >> On 10/03/2023 09:45, David Feuer wrote:
> >>
> >> 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.
> >>
> >> On Fri, Mar 10, 2023, 3:27 AM Tom Smeding <x at tomsmeding.com> wrote:
> >>>
> >>> Hi David,
> >>>
> >>> Fancy stuffs!
> >>>
> >>> Wondering how much magic was going on in implementing this, I saw that
> >>> atomicModifyIORef2Native misses the haddock marker '|' in the source;
> >>> thus your extensive doc comment doesn't show up on hackage.
> >>>
> >>> Cheers,
> >>> Tom
> >>>
> >>> On 10/03/2023 03:01, David Feuer wrote:
> >>> > I just put together a new package, atomic-modify-general, for
> >>> > generalizations of the `atomicModifyIORef` operation. In particular:
> >>> >
> >>> > 1. Versions that allow a result of an arbitrary type (not necessarily
> >>> > a pair), where the caller passes in an extraction function. These
> work
> >>> > with `Array` and `SmallArray` from `primitive` as well as `IORef`.
> >>> > 2. A version that works with record types (not just pairs) whose
> first
> >>> > field is the new value to install in the `IORef`. This uses
> >>> > implementation details of the `atomicModifyMutVar#` primop as well as
> >>> > GHC's heap object layout to achieve better performance.
> >>> >
> >>> > Please try it out and let me know how it goes, and what extras you
> may want!
> >>> >
> >>> > Hackage:
> https://hackage.haskell.org/package/atomic-modify-general-0.1.0.0
> >>> > _______________________________________________
> >>> > Haskell-Cafe mailing list
> >>> > To (un)subscribe, modify options or view archives go to:
> >>> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> >>> > Only members subscribed via the mailman list are allowed to post.
> >>>
> >>> _______________________________________________
> >>> Haskell-Cafe mailing list
> >>> To (un)subscribe, modify options or view archives go to:
> >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> >>> Only members subscribed via the mailman list are allowed to post.
> >>
> >>
> > _______________________________________________
> > Haskell-Cafe mailing list
> > To (un)subscribe, modify options or view archives go to:
> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > Only members subscribed via the mailman list are allowed to post.
>
>
>
> --
> brandon s allbery kf8nh
> allbery.b at gmail.com
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20230310/eb9ed179/attachment.html>


More information about the Haskell-Cafe mailing list