deepseq: Add more instances. #50

Greetings Haskellers, I am writing to draw your attention to https://github.com/haskell/deepseq/pull/50. This PR adds NFData instances for UArray, ForeignPtr, and TVar. The instances for ForeignPtr and TVar have proven to be somewhat controversial. I'll refer to these as "reference types" from here on out, since similar concerns have been raised with respect to e.g. IORef. I think the arguments presented here apply equally well to IORef. In summary: the argument against these instances is that rnf forces the evaluation of the reference value itself, not the value referred to by the reference. This is potentially confusing to NFData users. For example, a user might expect that calling force on a TVar value will leave the value to which the TVar refers in normal form. If this assumption doesn't hold, the user's program will leak thunks. The argument for these instances is as follows: whether or not a reference value is in normal form has nothing to do with whether or not the referred-to value is in normal form. For example, consider ForeignPtr. ForeignPtr's type constructor argument is just a phantom. Each ForeignPtr value is just an Addr# with some finalizers. Whether or not these values are in normal form has nothing to do with whether or not the value the enclosed address may (or may not!) point to is in normal form. Indeed, an NFData instance for ForeignPtr, TVar, or IORef that attempted to force the referred-to value would require unsafe IO. I'm curious to hear other's thoughts about these arguments. I'm hopeful that the proposed instances may be added, since I've encountered these instances as orphans on numerous occasions. Thanks for your time, Travis Whitaker

I think you've made an acceptable argument for these instances being
*reasonable*. The question is whether they're more *useful* or more
*confusing*. I'm currently leaning toward confusion. When do you actually
want to `deepSeq` something with references in it? I suppose it could
happen, but it's not likely to come up terribly often, is it?
On Tue, Jan 14, 2020, 7:55 PM Travis Whitaker
Greetings Haskellers,
I am writing to draw your attention to https://github.com/haskell/deepseq/pull/50.
This PR adds NFData instances for UArray, ForeignPtr, and TVar. The instances for ForeignPtr and TVar have proven to be somewhat controversial. I'll refer to these as "reference types" from here on out, since similar concerns have been raised with respect to e.g. IORef. I think the arguments presented here apply equally well to IORef.
In summary: the argument against these instances is that rnf forces the evaluation of the reference value itself, not the value referred to by the reference. This is potentially confusing to NFData users. For example, a user might expect that calling force on a TVar value will leave the value to which the TVar refers in normal form. If this assumption doesn't hold, the user's program will leak thunks.
The argument for these instances is as follows: whether or not a reference value is in normal form has nothing to do with whether or not the referred-to value is in normal form. For example, consider ForeignPtr. ForeignPtr's type constructor argument is just a phantom. Each ForeignPtr value is just an Addr# with some finalizers. Whether or not these values are in normal form has nothing to do with whether or not the value the enclosed address may (or may not!) point to is in normal form. Indeed, an NFData instance for ForeignPtr, TVar, or IORef that attempted to force the referred-to value would require unsafe IO.
I'm curious to hear other's thoughts about these arguments. I'm hopeful that the proposed instances may be added, since I've encountered these instances as orphans on numerous occasions.
Thanks for your time,
Travis Whitaker _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

Thanks for your email, David.
The NFData class is an important part of a large number of APIs on Hackage.
According to https://packdeps.haskellers.com/reverse, the deepseq package
has over 1,200 dependent packages. In my own case, I work with a lot of
record types with ForeignPtr fields. If I want to, say, use one of these
types as part of a Criterion environment for a benchmark, I will need an
NFData instance (
https://hackage.haskell.org/package/criterion-1.5.6.1/docs/Criterion.html#v:...
).
One might argue that any potentially confusing NFData instances should be
written out by hand. Maybe that's right, but now we're drifting into the
same territory as discussions about Foldable (,a). I've never needed to
take the length of a tuple, but the Foldable (,a) instance is lawful, so we
have it in base and I wouldn't be surprised if someone, somewhere is
thankful for that instance.
Travis
On Tue, Jan 14, 2020 at 5:24 PM David Feuer
I think you've made an acceptable argument for these instances being *reasonable*. The question is whether they're more *useful* or more *confusing*. I'm currently leaning toward confusion. When do you actually want to `deepSeq` something with references in it? I suppose it could happen, but it's not likely to come up terribly often, is it?
On Tue, Jan 14, 2020, 7:55 PM Travis Whitaker
wrote: Greetings Haskellers,
I am writing to draw your attention to https://github.com/haskell/deepseq/pull/50.
This PR adds NFData instances for UArray, ForeignPtr, and TVar. The instances for ForeignPtr and TVar have proven to be somewhat controversial. I'll refer to these as "reference types" from here on out, since similar concerns have been raised with respect to e.g. IORef. I think the arguments presented here apply equally well to IORef.
In summary: the argument against these instances is that rnf forces the evaluation of the reference value itself, not the value referred to by the reference. This is potentially confusing to NFData users. For example, a user might expect that calling force on a TVar value will leave the value to which the TVar refers in normal form. If this assumption doesn't hold, the user's program will leak thunks.
The argument for these instances is as follows: whether or not a reference value is in normal form has nothing to do with whether or not the referred-to value is in normal form. For example, consider ForeignPtr. ForeignPtr's type constructor argument is just a phantom. Each ForeignPtr value is just an Addr# with some finalizers. Whether or not these values are in normal form has nothing to do with whether or not the value the enclosed address may (or may not!) point to is in normal form. Indeed, an NFData instance for ForeignPtr, TVar, or IORef that attempted to force the referred-to value would require unsafe IO.
I'm curious to hear other's thoughts about these arguments. I'm hopeful that the proposed instances may be added, since I've encountered these instances as orphans on numerous occasions.
Thanks for your time,
Travis Whitaker _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

No one is thankful for the Foldable instance of tuples as far as I know.
Many of us tolerate it because we want the Traversable instance. But yes,
you make a point about Criterion. I hadn't considered that application.
On Tue, Jan 14, 2020, 10:03 PM Travis Whitaker
Thanks for your email, David.
The NFData class is an important part of a large number of APIs on Hackage. According to https://packdeps.haskellers.com/reverse, the deepseq package has over 1,200 dependent packages. In my own case, I work with a lot of record types with ForeignPtr fields. If I want to, say, use one of these types as part of a Criterion environment for a benchmark, I will need an NFData instance ( https://hackage.haskell.org/package/criterion-1.5.6.1/docs/Criterion.html#v:... ).
One might argue that any potentially confusing NFData instances should be written out by hand. Maybe that's right, but now we're drifting into the same territory as discussions about Foldable (,a). I've never needed to take the length of a tuple, but the Foldable (,a) instance is lawful, so we have it in base and I wouldn't be surprised if someone, somewhere is thankful for that instance.
Travis
On Tue, Jan 14, 2020 at 5:24 PM David Feuer
wrote: I think you've made an acceptable argument for these instances being *reasonable*. The question is whether they're more *useful* or more *confusing*. I'm currently leaning toward confusion. When do you actually want to `deepSeq` something with references in it? I suppose it could happen, but it's not likely to come up terribly often, is it?
On Tue, Jan 14, 2020, 7:55 PM Travis Whitaker
wrote: Greetings Haskellers,
I am writing to draw your attention to https://github.com/haskell/deepseq/pull/50.
This PR adds NFData instances for UArray, ForeignPtr, and TVar. The instances for ForeignPtr and TVar have proven to be somewhat controversial. I'll refer to these as "reference types" from here on out, since similar concerns have been raised with respect to e.g. IORef. I think the arguments presented here apply equally well to IORef.
In summary: the argument against these instances is that rnf forces the evaluation of the reference value itself, not the value referred to by the reference. This is potentially confusing to NFData users. For example, a user might expect that calling force on a TVar value will leave the value to which the TVar refers in normal form. If this assumption doesn't hold, the user's program will leak thunks.
The argument for these instances is as follows: whether or not a reference value is in normal form has nothing to do with whether or not the referred-to value is in normal form. For example, consider ForeignPtr. ForeignPtr's type constructor argument is just a phantom. Each ForeignPtr value is just an Addr# with some finalizers. Whether or not these values are in normal form has nothing to do with whether or not the value the enclosed address may (or may not!) point to is in normal form. Indeed, an NFData instance for ForeignPtr, TVar, or IORef that attempted to force the referred-to value would require unsafe IO.
I'm curious to hear other's thoughts about these arguments. I'm hopeful that the proposed instances may be added, since I've encountered these instances as orphans on numerous occasions.
Thanks for your time,
Travis Whitaker _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

David put my thoughts pretty clearly: is it more useful or more confusing?
I am also leaning toward more confusing. Hopefully more can weigh in on
this.
On Tue, Jan 14, 2020, 7:06 PM David Feuer
No one is thankful for the Foldable instance of tuples as far as I know. Many of us tolerate it because we want the Traversable instance. But yes, you make a point about Criterion. I hadn't considered that application.
On Tue, Jan 14, 2020, 10:03 PM Travis Whitaker
wrote: Thanks for your email, David.
The NFData class is an important part of a large number of APIs on Hackage. According to https://packdeps.haskellers.com/reverse, the deepseq package has over 1,200 dependent packages. In my own case, I work with a lot of record types with ForeignPtr fields. If I want to, say, use one of these types as part of a Criterion environment for a benchmark, I will need an NFData instance ( https://hackage.haskell.org/package/criterion-1.5.6.1/docs/Criterion.html#v:... ).
One might argue that any potentially confusing NFData instances should be written out by hand. Maybe that's right, but now we're drifting into the same territory as discussions about Foldable (,a). I've never needed to take the length of a tuple, but the Foldable (,a) instance is lawful, so we have it in base and I wouldn't be surprised if someone, somewhere is thankful for that instance.
Travis
On Tue, Jan 14, 2020 at 5:24 PM David Feuer
wrote: I think you've made an acceptable argument for these instances being *reasonable*. The question is whether they're more *useful* or more *confusing*. I'm currently leaning toward confusion. When do you actually want to `deepSeq` something with references in it? I suppose it could happen, but it's not likely to come up terribly often, is it?
On Tue, Jan 14, 2020, 7:55 PM Travis Whitaker
wrote: Greetings Haskellers,
I am writing to draw your attention to https://github.com/haskell/deepseq/pull/50.
This PR adds NFData instances for UArray, ForeignPtr, and TVar. The instances for ForeignPtr and TVar have proven to be somewhat controversial. I'll refer to these as "reference types" from here on out, since similar concerns have been raised with respect to e.g. IORef. I think the arguments presented here apply equally well to IORef.
In summary: the argument against these instances is that rnf forces the evaluation of the reference value itself, not the value referred to by the reference. This is potentially confusing to NFData users. For example, a user might expect that calling force on a TVar value will leave the value to which the TVar refers in normal form. If this assumption doesn't hold, the user's program will leak thunks.
The argument for these instances is as follows: whether or not a reference value is in normal form has nothing to do with whether or not the referred-to value is in normal form. For example, consider ForeignPtr. ForeignPtr's type constructor argument is just a phantom. Each ForeignPtr value is just an Addr# with some finalizers. Whether or not these values are in normal form has nothing to do with whether or not the value the enclosed address may (or may not!) point to is in normal form. Indeed, an NFData instance for ForeignPtr, TVar, or IORef that attempted to force the referred-to value would require unsafe IO.
I'm curious to hear other's thoughts about these arguments. I'm hopeful that the proposed instances may be added, since I've encountered these instances as orphans on numerous occasions.
Thanks for your time,
Travis Whitaker _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On Tue, 14 Jan 2020, chessai . wrote:
David put my thoughts pretty clearly: is it more useful or more confusing? I am also leaning toward more confusing. Hopefully more can weigh in on this.
I also think NFData instances for reference types are more dangerous than helpful. Since laziness and strictness account for subtle programming mistakes, it is better if GHC tells you that 'rnf tvar' does possibly not perform what you expect. I'd even consider to add an instance with a type error message to show the user that this instance has been omitted by intention.

I'd be in favor of adding the instances. Programming with pointers is hard and annoying. It's one of the reasons we like Haskell, where usually we don't have to worry about it. But if you are going to program with pointers, you already need to understand the notion of indirection, and so I don't think these instances will particularly throw people off. Richard
On Jan 15, 2020, at 7:55 AM, Henning Thielemann
wrote: On Tue, 14 Jan 2020, chessai . wrote:
David put my thoughts pretty clearly: is it more useful or more confusing? I am also leaning toward more confusing. Hopefully more can weigh in on this.
I also think NFData instances for reference types are more dangerous than helpful. Since laziness and strictness account for subtle programming mistakes, it is better if GHC tells you that 'rnf tvar' does possibly not perform what you expect. I'd even consider to add an instance with a type error message to show the user that this instance has been omitted by intention. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

I too agree that NFData instances for reference types are more trouble than worth the modest convenience they buy us. We don't have Show instances for reference-like types either and I don't think anybody would be arguing for those either.
John
On Wednesday, 15 January 2020, 07:55:40 UTC, Henning Thielemann
David put my thoughts pretty clearly: is it more useful or more confusing? I am also leaning toward more confusing. Hopefully more can weigh in on this.
I also think NFData instances for reference types are more dangerous than helpful. Since laziness and strictness account for subtle programming mistakes, it is better if GHC tells you that 'rnf tvar' does possibly not perform what you expect. I'd even consider to add an instance with a type error message to show the user that this instance has been omitted by intention. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

We do have Eq instances for those types, though, and they say that they compare the references rather than the values. Is NFData more like Eq or Show? On Wed, Jan 15, 2020, 02:59 John Villarreal via Libraries < libraries@haskell.org> wrote:
I too agree that NFData instances for reference types are more trouble than worth the modest convenience they buy us. We don't have Show instances for reference-like types either and I don't think anybody would be arguing for those either.
John
On Wednesday, 15 January 2020, 07:55:40 UTC, Henning Thielemann < lemming@henning-thielemann.de> wrote:
David put my thoughts pretty clearly: is it more useful or more confusing? I am also leaning toward more confusing. Hopefully more can weigh in on this.
I also think NFData instances for reference types are more dangerous than helpful. Since laziness and strictness account for subtle programming mistakes, it is better if GHC tells you that 'rnf tvar' does possibly not perform what you expect. I'd even consider to add an instance with a type error message to show the user that this instance has been omitted by intention.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

That's interesting! I do see Eq instances for types TVars and IORefs but no Ord instance. But I don't see an Eq instance defined for the (->) type which also seems to be considered a reference-like type in the discussion. However I do think the argument can be made that the Eq instance for reference types is equally questionable for similar reasons.
On Wednesday, 15 January 2020, 09:06:52 UTC, Zemyla
David put my thoughts pretty clearly: is it more useful or more confusing? I am also leaning toward more confusing. Hopefully more can weigh in on this.
I also think NFData instances for reference types are more dangerous than helpful. Since laziness and strictness account for subtle programming mistakes, it is better if GHC tells you that 'rnf tvar' does possibly not perform what you expect. I'd even consider to add an instance with a type error message to show the user that this instance has been omitted by intention. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

I would be in favor of adding these instances too. We could make it clear
in the documentation that the only thing being evaluated is the reference.
Am Mi., 15. Jan. 2020 um 10:07 Uhr schrieb Zemyla
We do have Eq instances for those types, though, and they say that they compare the references rather than the values. Is NFData more like Eq or Show?
On Wed, Jan 15, 2020, 02:59 John Villarreal via Libraries < libraries@haskell.org> wrote:
I too agree that NFData instances for reference types are more trouble than worth the modest convenience they buy us. We don't have Show instances for reference-like types either and I don't think anybody would be arguing for those either.
John
On Wednesday, 15 January 2020, 07:55:40 UTC, Henning Thielemann < lemming@henning-thielemann.de> wrote:
David put my thoughts pretty clearly: is it more useful or more confusing? I am also leaning toward more confusing. Hopefully more can weigh in on this.
I also think NFData instances for reference types are more dangerous than helpful. Since laziness and strictness account for subtle programming mistakes, it is better if GHC tells you that 'rnf tvar' does possibly not perform what you expect. I'd even consider to add an instance with a type error message to show the user that this instance has been omitted by intention.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

My understanding of the argument for and against is:
* For: Typeclass instances should be provided for as many types as
possible, and IORef, TVar, etc. only admit a single way to define NFData
* Against: Intuitively, NFData means that data is plain old sums and
products all the way down, all of which can be forced. This would mean that
anything with an NFData instance should be able to go into a compact region
(except that pinned byte arrays, and consequently bytestrings, cannot)
I'm inclined to agree with most of the opinions expressed earlier on the
thread. That is, given how minor the convenience is, the confusion is
probably not worth the convenience. I'll think about this more today.
On Tue, Jan 14, 2020 at 7:55 PM Travis Whitaker
Greetings Haskellers,
I am writing to draw your attention to https://github.com/haskell/deepseq/pull/50.
This PR adds NFData instances for UArray, ForeignPtr, and TVar. The instances for ForeignPtr and TVar have proven to be somewhat controversial. I'll refer to these as "reference types" from here on out, since similar concerns have been raised with respect to e.g. IORef. I think the arguments presented here apply equally well to IORef.
In summary: the argument against these instances is that rnf forces the evaluation of the reference value itself, not the value referred to by the reference. This is potentially confusing to NFData users. For example, a user might expect that calling force on a TVar value will leave the value to which the TVar refers in normal form. If this assumption doesn't hold, the user's program will leak thunks.
The argument for these instances is as follows: whether or not a reference value is in normal form has nothing to do with whether or not the referred-to value is in normal form. For example, consider ForeignPtr. ForeignPtr's type constructor argument is just a phantom. Each ForeignPtr value is just an Addr# with some finalizers. Whether or not these values are in normal form has nothing to do with whether or not the value the enclosed address may (or may not!) point to is in normal form. Indeed, an NFData instance for ForeignPtr, TVar, or IORef that attempted to force the referred-to value would require unsafe IO.
I'm curious to hear other's thoughts about these arguments. I'm hopeful that the proposed instances may be added, since I've encountered these instances as orphans on numerous occasions.
Thanks for your time,
Travis Whitaker _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- -Andrew Thaddeus Martin

As long as "Show" is the "other side of Read", a Show instance for
reference types is completely silly. NFData doesn't have *that* complication
at least.
On Wed, Jan 15, 2020 at 6:43 AM Andrew Martin
My understanding of the argument for and against is:
* For: Typeclass instances should be provided for as many types as possible, and IORef, TVar, etc. only admit a single way to define NFData * Against: Intuitively, NFData means that data is plain old sums and products all the way down, all of which can be forced. This would mean that anything with an NFData instance should be able to go into a compact region (except that pinned byte arrays, and consequently bytestrings, cannot)
I'm inclined to agree with most of the opinions expressed earlier on the thread. That is, given how minor the convenience is, the confusion is probably not worth the convenience. I'll think about this more today.
On Tue, Jan 14, 2020 at 7:55 PM Travis Whitaker
wrote: Greetings Haskellers,
I am writing to draw your attention to https://github.com/haskell/deepseq/pull/50.
This PR adds NFData instances for UArray, ForeignPtr, and TVar. The instances for ForeignPtr and TVar have proven to be somewhat controversial. I'll refer to these as "reference types" from here on out, since similar concerns have been raised with respect to e.g. IORef. I think the arguments presented here apply equally well to IORef.
In summary: the argument against these instances is that rnf forces the evaluation of the reference value itself, not the value referred to by the reference. This is potentially confusing to NFData users. For example, a user might expect that calling force on a TVar value will leave the value to which the TVar refers in normal form. If this assumption doesn't hold, the user's program will leak thunks.
The argument for these instances is as follows: whether or not a reference value is in normal form has nothing to do with whether or not the referred-to value is in normal form. For example, consider ForeignPtr. ForeignPtr's type constructor argument is just a phantom. Each ForeignPtr value is just an Addr# with some finalizers. Whether or not these values are in normal form has nothing to do with whether or not the value the enclosed address may (or may not!) point to is in normal form. Indeed, an NFData instance for ForeignPtr, TVar, or IORef that attempted to force the referred-to value would require unsafe IO.
I'm curious to hear other's thoughts about these arguments. I'm hopeful that the proposed instances may be added, since I've encountered these instances as orphans on numerous occasions.
Thanks for your time,
Travis Whitaker _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- -Andrew Thaddeus Martin _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

And similar to Show, many of us wish there was a *different *class that was
mostly for debugging, not for serialization. If there's a perception that
"NFData" means "able to be put in a compact region" then we definitely
don't want these instances. But perhaps what we want is two classes with
different guarantees.
On Wed, Jan 15, 2020 at 10:40 AM Elliot Cameron
As long as "Show" is the "other side of Read", a Show instance for reference types is completely silly. NFData doesn't have *that* complication at least.
On Wed, Jan 15, 2020 at 6:43 AM Andrew Martin
wrote: My understanding of the argument for and against is:
* For: Typeclass instances should be provided for as many types as possible, and IORef, TVar, etc. only admit a single way to define NFData * Against: Intuitively, NFData means that data is plain old sums and products all the way down, all of which can be forced. This would mean that anything with an NFData instance should be able to go into a compact region (except that pinned byte arrays, and consequently bytestrings, cannot)
I'm inclined to agree with most of the opinions expressed earlier on the thread. That is, given how minor the convenience is, the confusion is probably not worth the convenience. I'll think about this more today.
On Tue, Jan 14, 2020 at 7:55 PM Travis Whitaker
wrote: Greetings Haskellers,
I am writing to draw your attention to https://github.com/haskell/deepseq/pull/50.
This PR adds NFData instances for UArray, ForeignPtr, and TVar. The instances for ForeignPtr and TVar have proven to be somewhat controversial. I'll refer to these as "reference types" from here on out, since similar concerns have been raised with respect to e.g. IORef. I think the arguments presented here apply equally well to IORef.
In summary: the argument against these instances is that rnf forces the evaluation of the reference value itself, not the value referred to by the reference. This is potentially confusing to NFData users. For example, a user might expect that calling force on a TVar value will leave the value to which the TVar refers in normal form. If this assumption doesn't hold, the user's program will leak thunks.
The argument for these instances is as follows: whether or not a reference value is in normal form has nothing to do with whether or not the referred-to value is in normal form. For example, consider ForeignPtr. ForeignPtr's type constructor argument is just a phantom. Each ForeignPtr value is just an Addr# with some finalizers. Whether or not these values are in normal form has nothing to do with whether or not the value the enclosed address may (or may not!) point to is in normal form. Indeed, an NFData instance for ForeignPtr, TVar, or IORef that attempted to force the referred-to value would require unsafe IO.
I'm curious to hear other's thoughts about these arguments. I'm hopeful that the proposed instances may be added, since I've encountered these instances as orphans on numerous occasions.
Thanks for your time,
Travis Whitaker _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- -Andrew Thaddeus Martin _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

NFData predates compact regions by many years, and they've never been very
precisely matched.
On Wed, Jan 15, 2020, 10:42 AM Elliot Cameron
And similar to Show, many of us wish there was a *different *class that was mostly for debugging, not for serialization. If there's a perception that "NFData" means "able to be put in a compact region" then we definitely don't want these instances. But perhaps what we want is two classes with different guarantees.
On Wed, Jan 15, 2020 at 10:40 AM Elliot Cameron
wrote: As long as "Show" is the "other side of Read", a Show instance for reference types is completely silly. NFData doesn't have *that* complication at least.
On Wed, Jan 15, 2020 at 6:43 AM Andrew Martin
wrote: My understanding of the argument for and against is:
* For: Typeclass instances should be provided for as many types as possible, and IORef, TVar, etc. only admit a single way to define NFData * Against: Intuitively, NFData means that data is plain old sums and products all the way down, all of which can be forced. This would mean that anything with an NFData instance should be able to go into a compact region (except that pinned byte arrays, and consequently bytestrings, cannot)
I'm inclined to agree with most of the opinions expressed earlier on the thread. That is, given how minor the convenience is, the confusion is probably not worth the convenience. I'll think about this more today.
On Tue, Jan 14, 2020 at 7:55 PM Travis Whitaker
wrote: Greetings Haskellers,
I am writing to draw your attention to https://github.com/haskell/deepseq/pull/50.
This PR adds NFData instances for UArray, ForeignPtr, and TVar. The instances for ForeignPtr and TVar have proven to be somewhat controversial. I'll refer to these as "reference types" from here on out, since similar concerns have been raised with respect to e.g. IORef. I think the arguments presented here apply equally well to IORef.
In summary: the argument against these instances is that rnf forces the evaluation of the reference value itself, not the value referred to by the reference. This is potentially confusing to NFData users. For example, a user might expect that calling force on a TVar value will leave the value to which the TVar refers in normal form. If this assumption doesn't hold, the user's program will leak thunks.
The argument for these instances is as follows: whether or not a reference value is in normal form has nothing to do with whether or not the referred-to value is in normal form. For example, consider ForeignPtr. ForeignPtr's type constructor argument is just a phantom. Each ForeignPtr value is just an Addr# with some finalizers. Whether or not these values are in normal form has nothing to do with whether or not the value the enclosed address may (or may not!) point to is in normal form. Indeed, an NFData instance for ForeignPtr, TVar, or IORef that attempted to force the referred-to value would require unsafe IO.
I'm curious to hear other's thoughts about these arguments. I'm hopeful that the proposed instances may be added, since I've encountered these instances as orphans on numerous occasions.
Thanks for your time,
Travis Whitaker _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- -Andrew Thaddeus Martin _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

I don't understand what the NFData class has to do with compact regions. It's true that placing a value into a compact region causes it to be evaluated to normal form, but NFData instances are not used for this. In fact, there are objects that have a reasonable normal form but cannot be placed inside a compact region. StableName is an example of this, and it has an NFData instance already. Here's a GHCI session demonstrating this (GHC 8.6.5):
import Data.Compact import System.Mem.StableName x = 1 :: Int xsn <- makeStableName x c <- compact xsn *** Exception: compaction failed: cannot compact mutable objects import Control.DeepSeq rnf xsn ()
On Wed, Jan 15, 2020 at 3:43 AM Andrew Martin
My understanding of the argument for and against is:
* For: Typeclass instances should be provided for as many types as possible, and IORef, TVar, etc. only admit a single way to define NFData * Against: Intuitively, NFData means that data is plain old sums and products all the way down, all of which can be forced. This would mean that anything with an NFData instance should be able to go into a compact region (except that pinned byte arrays, and consequently bytestrings, cannot)
I'm inclined to agree with most of the opinions expressed earlier on the thread. That is, given how minor the convenience is, the confusion is probably not worth the convenience. I'll think about this more today.
On Tue, Jan 14, 2020 at 7:55 PM Travis Whitaker
wrote: Greetings Haskellers,
I am writing to draw your attention to https://github.com/haskell/deepseq/pull/50.
This PR adds NFData instances for UArray, ForeignPtr, and TVar. The instances for ForeignPtr and TVar have proven to be somewhat controversial. I'll refer to these as "reference types" from here on out, since similar concerns have been raised with respect to e.g. IORef. I think the arguments presented here apply equally well to IORef.
In summary: the argument against these instances is that rnf forces the evaluation of the reference value itself, not the value referred to by the reference. This is potentially confusing to NFData users. For example, a user might expect that calling force on a TVar value will leave the value to which the TVar refers in normal form. If this assumption doesn't hold, the user's program will leak thunks.
The argument for these instances is as follows: whether or not a reference value is in normal form has nothing to do with whether or not the referred-to value is in normal form. For example, consider ForeignPtr. ForeignPtr's type constructor argument is just a phantom. Each ForeignPtr value is just an Addr# with some finalizers. Whether or not these values are in normal form has nothing to do with whether or not the value the enclosed address may (or may not!) point to is in normal form. Indeed, an NFData instance for ForeignPtr, TVar, or IORef that attempted to force the referred-to value would require unsafe IO.
I'm curious to hear other's thoughts about these arguments. I'm hopeful that the proposed instances may be added, since I've encountered these instances as orphans on numerous occasions.
Thanks for your time,
Travis Whitaker _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- -Andrew Thaddeus Martin

As I understand, the case for against is: I have a space leak, I'll try rnf
on this data. Space leak is still present, so it must not be due to that
data, so I go to the next idea. But if there's something in there that rnf
silently skipped, then I'll be misled. It would be nice if the compiler
will warn me where the possibly leaking bits that rnf can't help with,
which is presumably closures and explicit pointers.
On Wed, Jan 15, 2020, 3:43 AM Andrew Martin
My understanding of the argument for and against is:
* For: Typeclass instances should be provided for as many types as possible, and IORef, TVar, etc. only admit a single way to define NFData * Against: Intuitively, NFData means that data is plain old sums and products all the way down, all of which can be forced. This would mean that anything with an NFData instance should be able to go into a compact region (except that pinned byte arrays, and consequently bytestrings, cannot)
I'm inclined to agree with most of the opinions expressed earlier on the thread. That is, given how minor the convenience is, the confusion is probably not worth the convenience. I'll think about this more today.
On Tue, Jan 14, 2020 at 7:55 PM Travis Whitaker
wrote: Greetings Haskellers,
I am writing to draw your attention to https://github.com/haskell/deepseq/pull/50.
This PR adds NFData instances for UArray, ForeignPtr, and TVar. The instances for ForeignPtr and TVar have proven to be somewhat controversial. I'll refer to these as "reference types" from here on out, since similar concerns have been raised with respect to e.g. IORef. I think the arguments presented here apply equally well to IORef.
In summary: the argument against these instances is that rnf forces the evaluation of the reference value itself, not the value referred to by the reference. This is potentially confusing to NFData users. For example, a user might expect that calling force on a TVar value will leave the value to which the TVar refers in normal form. If this assumption doesn't hold, the user's program will leak thunks.
The argument for these instances is as follows: whether or not a reference value is in normal form has nothing to do with whether or not the referred-to value is in normal form. For example, consider ForeignPtr. ForeignPtr's type constructor argument is just a phantom. Each ForeignPtr value is just an Addr# with some finalizers. Whether or not these values are in normal form has nothing to do with whether or not the value the enclosed address may (or may not!) point to is in normal form. Indeed, an NFData instance for ForeignPtr, TVar, or IORef that attempted to force the referred-to value would require unsafe IO.
I'm curious to hear other's thoughts about these arguments. I'm hopeful that the proposed instances may be added, since I've encountered these instances as orphans on numerous occasions.
Thanks for your time,
Travis Whitaker _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- -Andrew Thaddeus Martin _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

aka, we shouldn't provide instances for stuff thats not "NF'able", so that
these tricky bits aren't invisible, right?
On Wed, Jan 15, 2020 at 8:37 PM Evan Laforge
As I understand, the case for against is: I have a space leak, I'll try rnf on this data. Space leak is still present, so it must not be due to that data, so I go to the next idea. But if there's something in there that rnf silently skipped, then I'll be misled. It would be nice if the compiler will warn me where the possibly leaking bits that rnf can't help with, which is presumably closures and explicit pointers.
On Wed, Jan 15, 2020, 3:43 AM Andrew Martin
wrote: My understanding of the argument for and against is:
* For: Typeclass instances should be provided for as many types as possible, and IORef, TVar, etc. only admit a single way to define NFData * Against: Intuitively, NFData means that data is plain old sums and products all the way down, all of which can be forced. This would mean that anything with an NFData instance should be able to go into a compact region (except that pinned byte arrays, and consequently bytestrings, cannot)
I'm inclined to agree with most of the opinions expressed earlier on the thread. That is, given how minor the convenience is, the confusion is probably not worth the convenience. I'll think about this more today.
On Tue, Jan 14, 2020 at 7:55 PM Travis Whitaker
wrote: Greetings Haskellers,
I am writing to draw your attention to https://github.com/haskell/deepseq/pull/50.
This PR adds NFData instances for UArray, ForeignPtr, and TVar. The instances for ForeignPtr and TVar have proven to be somewhat controversial. I'll refer to these as "reference types" from here on out, since similar concerns have been raised with respect to e.g. IORef. I think the arguments presented here apply equally well to IORef.
In summary: the argument against these instances is that rnf forces the evaluation of the reference value itself, not the value referred to by the reference. This is potentially confusing to NFData users. For example, a user might expect that calling force on a TVar value will leave the value to which the TVar refers in normal form. If this assumption doesn't hold, the user's program will leak thunks.
The argument for these instances is as follows: whether or not a reference value is in normal form has nothing to do with whether or not the referred-to value is in normal form. For example, consider ForeignPtr. ForeignPtr's type constructor argument is just a phantom. Each ForeignPtr value is just an Addr# with some finalizers. Whether or not these values are in normal form has nothing to do with whether or not the value the enclosed address may (or may not!) point to is in normal form. Indeed, an NFData instance for ForeignPtr, TVar, or IORef that attempted to force the referred-to value would require unsafe IO.
I'm curious to hear other's thoughts about these arguments. I'm hopeful that the proposed instances may be added, since I've encountered these instances as orphans on numerous occasions.
Thanks for your time,
Travis Whitaker _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- -Andrew Thaddeus Martin _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

"inNeeFable", i love this pun too much :)
cf https://www.merriam-webster.com/dictionary/ineffable
On Fri, Feb 7, 2020 at 1:59 PM Carter Schonwald
aka, we shouldn't provide instances for stuff thats not "NF'able", so that these tricky bits aren't invisible, right?
On Wed, Jan 15, 2020 at 8:37 PM Evan Laforge
wrote: As I understand, the case for against is: I have a space leak, I'll try rnf on this data. Space leak is still present, so it must not be due to that data, so I go to the next idea. But if there's something in there that rnf silently skipped, then I'll be misled. It would be nice if the compiler will warn me where the possibly leaking bits that rnf can't help with, which is presumably closures and explicit pointers.
On Wed, Jan 15, 2020, 3:43 AM Andrew Martin
wrote: My understanding of the argument for and against is:
* For: Typeclass instances should be provided for as many types as possible, and IORef, TVar, etc. only admit a single way to define NFData * Against: Intuitively, NFData means that data is plain old sums and products all the way down, all of which can be forced. This would mean that anything with an NFData instance should be able to go into a compact region (except that pinned byte arrays, and consequently bytestrings, cannot)
I'm inclined to agree with most of the opinions expressed earlier on the thread. That is, given how minor the convenience is, the confusion is probably not worth the convenience. I'll think about this more today.
On Tue, Jan 14, 2020 at 7:55 PM Travis Whitaker
wrote: Greetings Haskellers,
I am writing to draw your attention to https://github.com/haskell/deepseq/pull/50.
This PR adds NFData instances for UArray, ForeignPtr, and TVar. The instances for ForeignPtr and TVar have proven to be somewhat controversial. I'll refer to these as "reference types" from here on out, since similar concerns have been raised with respect to e.g. IORef. I think the arguments presented here apply equally well to IORef.
In summary: the argument against these instances is that rnf forces the evaluation of the reference value itself, not the value referred to by the reference. This is potentially confusing to NFData users. For example, a user might expect that calling force on a TVar value will leave the value to which the TVar refers in normal form. If this assumption doesn't hold, the user's program will leak thunks.
The argument for these instances is as follows: whether or not a reference value is in normal form has nothing to do with whether or not the referred-to value is in normal form. For example, consider ForeignPtr. ForeignPtr's type constructor argument is just a phantom. Each ForeignPtr value is just an Addr# with some finalizers. Whether or not these values are in normal form has nothing to do with whether or not the value the enclosed address may (or may not!) point to is in normal form. Indeed, an NFData instance for ForeignPtr, TVar, or IORef that attempted to force the referred-to value would require unsafe IO.
I'm curious to hear other's thoughts about these arguments. I'm hopeful that the proposed instances may be added, since I've encountered these instances as orphans on numerous occasions.
Thanks for your time,
Travis Whitaker _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- -Andrew Thaddeus Martin _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
participants (12)
-
Andrew Martin
-
Carter Schonwald
-
chessai .
-
Daniel Díaz Casanueva
-
David Feuer
-
Elliot Cameron
-
Evan Laforge
-
Henning Thielemann
-
John Villarreal
-
Richard Eisenberg
-
Travis Whitaker
-
Zemyla