ANNOUNCE: deepseq-1.0.0.0

I've just uploaded deepseq-1.0.0.0 to Hackage http://hackage.haskell.org/package/deepseq This provides a DeepSeq class with a deepseq method, equivalent to the existing NFData/rnf in the parallel package. I'll be using this in a newly revamped parallel package, which I hope to upload shortly. Cheers, Simon

On Tue, Nov 17, 2009 at 12:00 PM, Simon Marlow
I've just uploaded deepseq-1.0.0.0 to Hackage
This is great! I often use rnf to fully evaluate some expression where I didn't need parallelism at all. Time to update some packages. Thank you, Roel

Hello,
The release of the regular library for generic programming on Hackage
[1] also contains a form of deep seq [2]. This means that you don't
even have to write the definition of 'deepseq', you can just use
'gdseq' (assuming you have used Template Haskell to derive the generic
representations for your types).
Cheers,
Pedro
[1] http://hackage.haskell.org/package/regular
[2] http://hackage.haskell.org/packages/archive/regular/0.2.1/doc/html/Generics-...
On Tue, Nov 17, 2009 at 12:04, Roel van Dijk
On Tue, Nov 17, 2009 at 12:00 PM, Simon Marlow
wrote: I've just uploaded deepseq-1.0.0.0 to Hackage
This is great! I often use rnf to fully evaluate some expression where I didn't need parallelism at all. Time to update some packages.
Thank you, Roel _______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Excerpts from Simon Marlow's message of Tue Nov 17 12:00:21 +0100 2009:
I've just uploaded deepseq-1.0.0.0 to Hackage
Great! I'm wondering what is the need/purpose for DeepSeqIntegral and DeepSeqOrd? -- Nicolas Pouillard http://nicolaspouillard.fr

On 17/11/2009 12:25, Nicolas Pouillard wrote:
Excerpts from Simon Marlow's message of Tue Nov 17 12:00:21 +0100 2009:
I've just uploaded deepseq-1.0.0.0 to Hackage
Great!
I'm wondering what is the need/purpose for DeepSeqIntegral and DeepSeqOrd?
I don't actually know, they were previously NFDataIntegral and NFDataOrd respectively. Unless anyone can think of a reason to want these, I'll remove them. Cheers, Simon

Excerpts from Simon Marlow's message of Wed Nov 18 09:55:28 +0100 2009:
On 17/11/2009 12:25, Nicolas Pouillard wrote:
Excerpts from Simon Marlow's message of Tue Nov 17 12:00:21 +0100 2009:
I've just uploaded deepseq-1.0.0.0 to Hackage
Great!
I'm wondering what is the need/purpose for DeepSeqIntegral and DeepSeqOrd?
I don't actually know, they were previously NFDataIntegral and NFDataOrd respectively. Unless anyone can think of a reason to want these, I'll remove them.
No one claimed for them, I think and are just useless, and thus confusing. Best regards, -- Nicolas Pouillard http://nicolaspouillard.fr

On 28/11/09 14:04, Nicolas Pouillard wrote:
Excerpts from Simon Marlow's message of Wed Nov 18 09:55:28 +0100 2009:
On 17/11/2009 12:25, Nicolas Pouillard wrote:
Excerpts from Simon Marlow's message of Tue Nov 17 12:00:21 +0100 2009:
I've just uploaded deepseq-1.0.0.0 to Hackage
Great!
I'm wondering what is the need/purpose for DeepSeqIntegral and DeepSeqOrd?
I don't actually know, they were previously NFDataIntegral and NFDataOrd respectively. Unless anyone can think of a reason to want these, I'll remove them.
No one claimed for them, I think and are just useless, and thus confusing.
Already gone in deepseq-1.1.0.0, which also renamed DeepSeq back to NFData. Cheers, Simon

On Tue, 2009-11-17 at 11:00 +0000, Simon Marlow wrote:
I've just uploaded deepseq-1.0.0.0 to Hackage
http://hackage.haskell.org/package/deepseq
This provides a DeepSeq class with a deepseq method, equivalent to the existing NFData/rnf in the parallel package. I'll be using this in a newly revamped parallel package, which I hope to upload shortly.
Yay, you get to be the first person to try out the new platform package proposal process! http://trac.haskell.org/haskell-platform/wiki/AddingPackages (because it's a new dependency of a platform package) Duncan

On Tue, Nov 17, 2009 at 3:00 AM, Simon Marlow
I've just uploaded deepseq-1.0.0.0 to Hackage
http://hackage.haskell.org/package/deepseq
This provides a DeepSeq class with a deepseq method, equivalent to the existing NFData/rnf in the parallel package. http://www.haskell.org/mailman/listinfo/haskell-cafe
If it's equivalent, what are the relevant differences? Why would I choose DeepSeq over NFData or vice versa?

On Nov 17, 2009, at 11:36 , Bryan O'Sullivan wrote:
On Tue, Nov 17, 2009 at 3:00 AM, Simon Marlow
wrote: I've just uploaded deepseq-1.0.0.0 to Hackage http://hackage.haskell.org/package/deepseq
This provides a DeepSeq class with a deepseq method, equivalent to the existing NFData/rnf in the parallel package.
If it's equivalent, what are the relevant differences? Why would I choose DeepSeq over NFData or vice versa?
Considering that he said he's going to be using it in parallel, the difference is merely that it's usable *without* parallel. It's about dependencies, not functionality. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On 17/11/2009 18:42, Brandon S. Allbery KF8NH wrote:
On Nov 17, 2009, at 11:36 , Bryan O'Sullivan wrote:
On Tue, Nov 17, 2009 at 3:00 AM, Simon Marlow
mailto:marlowsd@gmail.com> wrote: I've just uploaded deepseq-1.0.0.0 to Hackage
http://hackage.haskell.org/package/deepseq
This provides a DeepSeq class with a deepseq method, equivalent to the existing NFData/rnf in the parallel package. http://www.haskell.org/mailman/listinfo/haskell-cafe
If it's equivalent, what are the relevant differences? Why would I choose DeepSeq over NFData or vice versa?
Considering that he said he's going to be using it in parallel, the difference is merely that it's usable *without* parallel. It's about dependencies, not functionality.
Yes, that's exactly it. No new functionality relative to NFData, just moving it to a more appropriate place. Cheers, Simon

At 11:00 AM +0000 11/17/09, Simon Marlow wrote:
I've just uploaded deepseq-1.0.0.0 to Hackage
http://hackage.haskell.org/package/deepseq
This provides a DeepSeq class with a deepseq method, equivalent to the existing NFData/rnf in the parallel package. I'll be using this in a newly revamped parallel package, which I hope to upload shortly.
Cheers, Simon
The documentation claim that "The default implementation of 'deepseq' is simply 'seq'" is not exactly right, as `deepseq` and `seq` have different signatures. Which raises the more interesting question: Why did you choose a different signature? And, would a version of `seq` with the same signature as `deepseq` be useful? Dean

The documentation claim that "The default implementation of 'deepseq' is simply 'seq'" is not exactly right, as `deepseq` and `seq` have different signatures.
Yes indeed. In order to use deepseq, it looks like I also need some way to force the () return value, e.g. let res = deepseq (my big computation) in res `seq` use res or let res = deepseq (my big computation) in case res of () -> use res I suppose the advantage of this approach is to ensure that the user must let-bind the forced value to a name. A beginner might write (my big computation) `seq` use (my big computation) without realising that it fails to do what they desire. Regards, Malcolm

On 18/11/2009 04:05, Malcolm Wallace wrote:
The documentation claim that "The default implementation of 'deepseq' is simply 'seq'" is not exactly right, as `deepseq` and `seq` have different signatures.
Yes indeed. In order to use deepseq, it looks like I also need some way to force the () return value, e.g.
let res = deepseq (my big computation) in res `seq` use res
or
let res = deepseq (my big computation) in case res of () -> use res
or let !res = deepseq (my big computation) in use res Cheers, Simon

On 18/11/2009 03:48, Dean Herington wrote:
At 11:00 AM +0000 11/17/09, Simon Marlow wrote:
I've just uploaded deepseq-1.0.0.0 to Hackage
http://hackage.haskell.org/package/deepseq
This provides a DeepSeq class with a deepseq method, equivalent to the existing NFData/rnf in the parallel package. I'll be using this in a newly revamped parallel package, which I hope to upload shortly.
Cheers, Simon
The documentation claim that "The default implementation of 'deepseq' is simply 'seq'" is not exactly right, as `deepseq` and `seq` have different signatures. Which raises the more interesting question: Why did you choose a different signature? And, would a version of `seq` with the same signature as `deepseq` be useful?
So the main difference is that with the current formulation of deepseq, you need to explicitly force the result in order to use it, either with a pattern match, another seq, or a pseq. If we used (a -> b -> b) then the top-level forcing is "built-in". Let's look at an example instance; here (1) is the current deepseq, (2) is deepseq :: a -> b -> b instance (DeepSeq a, DeepSeq b) => DeepSeq (a,b) where -- (1) deepseq (a,b) = deepseq a `seq` deepseq b -- (2) deepseq (a,b) = deepseq a . deepseq b They're both fairly similar. Most instances follow this pattern, with seq being replaced by (.). You could argue that (a -> b -> b) is "doing more" than (a -> ()), because it has a kind of built-in continuation (Luke's point). I buy that, although (a -> ()) has a strange-looking unit type in the result and you have to use it in conjunction with seq. (1) generates slightly better code with GHC, because it compiles seq directly into a case expression, whereas (.) involves a thunk. If deepseq is inlined all the way down, then it would turn into the same thing either way. I don't feel terribly strongly, but I have a slight preference for the current version. Cheers, Simon

Hello Simon, Wednesday, November 18, 2009, 12:17:31 PM, you wrote:
You could argue that (a -> b -> b) is "doing more" than (a -> ()),
if i correctly understand, we have two versions: 1) easier to use 2) more efficient and one of them may be defined via another? how about providing both versions, with simpler name for simpler version? -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

On Wed, Nov 18, 2009 at 09:17:31AM +0000, Simon Marlow wrote:
I don't feel terribly strongly, but I have a slight preference for the current version.
I think something like deepseq :: a -> (a -> b) -> b would be best, so that it doesn't suffer from http://hackage.haskell.org/trac/ghc/ticket/2273 Thanks Ian

On 18/11/2009 12:12, Ian Lynagh wrote:
On Wed, Nov 18, 2009 at 09:17:31AM +0000, Simon Marlow wrote:
I don't feel terribly strongly, but I have a slight preference for the current version.
I think something like
deepseq :: a -> (a -> b) -> b
would be best, so that it doesn't suffer from
I don't mind supplying that too, with a comment to explain why it's there. Although we could recommend that people use the bang-pattern idiom instead, where that's available. The main question still to be resolved is what names to use. I agree with Duncan's point that deepseq should have the same type as seq, to reduce confusion. So then what shall we call the a -> () version? One possibility is to go back to calling it rnf. Any other ideas? Cheers, Simon

Yitzchak Gale wrote:
Simon Marlow wrote:
So then what shall we call the a -> () version? One possibility is to go back to calling it rnf.
In light of apfelmus' comment, I vote for rnf.
And in that case, how about the analogous alternative for seq itself:
hnf :: a -> ()
I think it would be whnf since it doesn't evaluate under lambdas. I also vote for rnf, because we should have a good reason for changing names of things. Ganesh =============================================================================== Please access the attached hyperlink for an important electronic communications disclaimer: http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html ===============================================================================

On 19/11/2009 11:52, Sittampalam, Ganesh wrote:
Yitzchak Gale wrote:
Simon Marlow wrote:
So then what shall we call the a -> () version? One possibility is to go back to calling it rnf.
In light of apfelmus' comment, I vote for rnf.
And in that case, how about the analogous alternative for seq itself:
hnf :: a -> ()
I think it would be whnf since it doesn't evaluate under lambdas.
I also vote for rnf, because we should have a good reason for changing names of things.
Various people would prefer rnf. Ok, unless there are any further objections, I'll change the names back to class NFData a where rnf :: a -> () and also add deepseq :: a -> b -> b but I'll leave the module name as Control.DeepSeq. Cheers, Simon

On 19/11/09 12:17, Simon Marlow wrote:
Ok, unless there are any further objections, I'll change the names back to
class NFData a where rnf :: a -> ()
and also add
deepseq :: a -> b -> b
but I'll leave the module name as Control.DeepSeq.
I made this change and uploaded deepseq-1.1.0.0 on Friday. There's also an updated parallel-2.1.0.0, but after discussions with Phil Trinder and other Parallel Haskell gurus, I think there may be further changes forthcoming. Upshot: the new version of parallel is still changing, you might want to wait until things settle down (hopefully not long) before switching. Cheers, Simon

Hello Simon, Thursday, November 19, 2009, 2:36:12 PM, you wrote:
The main question still to be resolved is what names to use. I agree with Duncan's point that deepseq should have the same type as seq, to reduce confusion. So then what shall we call the a -> () version?
not that i vote for it, just idea: deepseq_ like monadic *_ functions -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

On Wed, 2009-11-18 at 09:17 +0000, Simon Marlow wrote:
So the main difference is that with the current formulation of deepseq, you need to explicitly force the result in order to use it, either with a pattern match, another seq, or a pseq. If we used (a -> b -> b) then the top-level forcing is "built-in".
Let's look at an example instance; here (1) is the current deepseq, (2) is deepseq :: a -> b -> b
instance (DeepSeq a, DeepSeq b) => DeepSeq (a,b) where -- (1) deepseq (a,b) = deepseq a `seq` deepseq b -- (2) deepseq (a,b) = deepseq a . deepseq b
They're both fairly similar. Most instances follow this pattern, with seq being replaced by (.).
You could argue that (a -> b -> b) is "doing more" than (a -> ()), because it has a kind of built-in continuation (Luke's point). I buy that, although (a -> ()) has a strange-looking unit type in the result and you have to use it in conjunction with seq.
I think the most important thing is to make the public interface that people use most frequently simple and easy to remember. Thus I suggest the primary function people use should be deepseq :: DeepSeq a => a -> b -> b because then all that users have to remember is: "deepseq --- like seq but more so!" That's it. Users already know how to use seq, so now they know how to use deepseq too.
(1) generates slightly better code with GHC, because it compiles seq directly into a case expression, whereas (.) involves a thunk. If deepseq is inlined all the way down, then it would turn into the same thing either way.
I don't feel terribly strongly, but I have a slight preference for the current version.
If it so happens that it is more convenient or faster to make the class and instances use the (a -> ()) style then that is fine. We can give the class method a different name. Presumably people have to write Deepseq instances much less frequently than they use deepseq. Duncan
participants (13)
-
Brandon S. Allbery KF8NH
-
Bryan O'Sullivan
-
Bulat Ziganshin
-
Dean Herington
-
Duncan Coutts
-
Ian Lynagh
-
José Pedro Magalhães
-
Malcolm Wallace
-
Nicolas Pouillard
-
Roel van Dijk
-
Simon Marlow
-
Sittampalam, Ganesh
-
Yitzchak Gale