TravisWhitaker · GitHub

I'm confused about what the Rec/NoRec wrappers have to do with the instances proposed in this PR. UArray, ForeignPtr, and TVar are not recursive types, and although their type constructors take arguments, whether or not values of type UArray i a/ForeignPtr a/TVar a are in normal form have nothing to do with what the argument type a is, or indeed any values of type a. These types have no a in their structures at all; for example, I can easily construct a value of type ForeignPtr Void that is in normal form.

I've been working with this definition of "normal form:" values in normal form can not be reduced any further, i.e.

  • The constructor is determined.
  • The constructor's arguments are not thunks.
  • The constructor's arguments are in normal form.

This is subtle in the case of some reference types, since the reference's constructors don't contain the referenced type. Consider ForeignPtr for example. Values of type ForeignPtr a may reference values of type a, even though the ForeignPtr constructor and its arguments don't hold a value of type a. Because a ForeignPtr a is really just an Addr# with some finalizers, we can use the exact same normalization strategy no matter what a is. The normalized values yielded by the instances in this PR are not in WHNF even though rwhnf is a sufficient implementation (except for ForeignPtr, which is strict in the Addr# but not the finalizers). A ForeignPtr with a known Addr# is a real normal form value, unlike, for example, the values yielded by the NFData (a -> b) instance (although I might be wrong about this, since I don't know what a function's normal form is) . Since this is a strategy that yields correct normal forms, I don't think it warrants a special wrapper.

It would be a mistake to dereference the a that a ForeignPtr might point to (e.g. nullPtr can be made into a ForeignPtr), since the referenced value has nothing to do with whether or not a ForeignPtr value is in normal form. Indeed, I have a library that would segfault if the NFData (ForeignPtr a) instance attempted to dereference and normalize the referenced a values.

I suspect that Herbert simply hasn't had the time to review this PR or participate in this conversation. I'll shoot him an email, since that seems to be his preference these days.

Read the original on github.com ↗