deepseq: Add more instances. #50

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
20 messages Options
Reply | Threaded
Open this post in threaded view
|

deepseq: Add more instances. #50

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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

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:env).

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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

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 <[hidden email]> 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:env).

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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

chessai .
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 <[hidden email]> wrote:
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 <[hidden email]> 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:env).

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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

Henning Thielemann

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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

Richard Eisenberg-5
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 <[hidden email]> 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
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

Haskell - Libraries mailing list
In reply to this post by Henning Thielemann
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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

Haskell - Libraries mailing list
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 <[hidden email]> wrote:


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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

Travis Whitaker
In reply to this post by Henning Thielemann
If the Control.DeepSeq module exports an error-yielding instance, then one would need to newtype all their ForeignPtrs in order to define their own correct NFData instance. Naturally I’m biased, but that seems like quite a hoop to jump through to get correct but subtle behavior. I’m not sure the core libraries go to such lengths to hide correct-but-tricky behavior anywhere else; I’d be interested in seeing existing examples of this.

On Wed, Jan 15, 2020 at 1:13 AM Henning Thielemann <[hidden email]> wrote:

On Wed, 15 Jan 2020, Travis Whitaker wrote:

> If such an error-yielding instance were added, how would users who need
> the correct-but-potentially-confusing behaving NFData instance cope with
> this?

In the criterion/record example they would manually implement the NFData
instance for the record, as you already suggested.

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

Daniel Díaz Casanueva
In reply to this post by Zemyla
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 <[hidden email]>:
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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

Andrew Martin
In reply to this post by Travis Whitaker
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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


--
-Andrew Thaddeus Martin

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

Elliot Cameron-2
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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


--
-Andrew Thaddeus Martin
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

Elliot Cameron-2
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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


--
-Andrew Thaddeus Martin
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

David Feuer
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 <[hidden email]> wrote:
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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


--
-Andrew Thaddeus Martin
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

Travis Whitaker
In reply to this post by Andrew Martin
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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


--
-Andrew Thaddeus Martin

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

Evan Laforge
In reply to this post by Andrew 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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


--
-Andrew Thaddeus Martin
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


--
-Andrew Thaddeus Martin
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: deepseq: Add more instances. #50

Carter Schonwald
"inNeeFable", i love this pun too much :)

On Fri, Feb 7, 2020 at 1:59 PM Carter Schonwald <[hidden email]> wrote:
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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


--
-Andrew Thaddeus Martin
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries