haskell / primitive

This package provides various primitive memory-related operations.
Other
114 stars 58 forks source link

Add support for weak references with unlifted keys #210

Open treeowl opened 6 years ago

treeowl commented 6 years ago

We should be able to write

mkWeakFromUnlifted
  :: (PrimUnlifted k, PrimMonad m, PrimState m ~ RealWorld)
  => k -> v -> IO () -> m (Weak v)

We should also be able to write a (nasty) type

newtype WeakUnlifted a =
  WeakUnlifted (Weak Any)
type role WeakUnlifted representational

This would allow weak references containing unlifted values. The GHC primops language doesn't seem to know how to express such a primitive type yet, although it's conceptually simple. We'd end up with four fundamental creation functions.

Relatedly, we should offer

touchUnlifted
  :: (PrimUnlifted a, PrimMonad m, PrimState m ~ RealWorld)
  => a -> m ()
touchUnlifted a =
  primitive_ $ touch# (toUnlifted# a)
cartazio commented 6 years ago

andrew and I spoke about weak references a while ago, and one concern we had is that they wont be safe outside of the IO monad, or some generalization thereof

do we have any applications or benchmarks to motivate this work for now?

On Thu, Aug 30, 2018 at 5:44 PM David Feuer notifications@github.com wrote:

We should be able to write

mkWeakFromUnlifted :: PrimUnlifted k => k -> v -> IO -> IO (Weak v)

We should also be able to write a (nasty) type

newtype WeakUnlifted a = WeakUnlifted (Weak Any)type role WeakUnlifted representational

This would allow weak references containing unlifted values. The GHC primops language doesn't seem to know how to express such a primitive type yet, although it's conceptually simple. We'd end up with four fundamental creation functions.

Relatedly, we should offer

touchUnlifted :: PrimUnlifted a => a -> IO () touchUnlifted a = IO $ \s -> (# touch# (toUnlifted# a), () #)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/haskell/primitive/issues/210, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAQwuJaWeSKKBYqx0XBjB5Pm4TDMDziks5uWFy_gaJpZM4WURSp .

treeowl commented 6 years ago

I'm not talking about generalizing beyond IO (or PrimState m ~ RealWorld), but about building on the UnliftedPrim class.

treeowl commented 6 years ago

Weak references with boxed keys aren't very reliable. See the documentation on mkWeakIORef. We can cover all the unlifted types in one go with PrimUnlifted so users don't need a separate function for each.

Weak references to boxed things seem pretty bad if you're storing a bunch of them at once (e.g., in an UnliftedArray). They add an extra O(n) heap objects that are completely unnecessary, with the associated indirection and GC costs. Weak pointers aren't the most efficient things in the world anyway, but that doesn't seem like a great excuse to be even less efficient.