Re: [Haskell-cafe] Re: ANNOUNCE: deepseq-1.0.0.0

2009-11-19 Thread Simon Marlow

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
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: ANNOUNCE: deepseq-1.0.0.0

2009-11-18 Thread Bulat Ziganshin
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,
 Bulatmailto:bulat.zigans...@gmail.com

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: ANNOUNCE: deepseq-1.0.0.0

2009-11-18 Thread Duncan Coutts
On Wed, 2009-11-18 at 09:17 +, 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

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: ANNOUNCE: deepseq-1.0.0.0

2009-11-17 Thread Luke Palmer
On Tue, Nov 17, 2009 at 8:48 PM, Dean Herington
heringtonla...@mindspring.com wrote:
 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?

The situation is analogous to, say, null having this signature:

null :: [a] - Bool

Instead of this one:

null :: [a] - b - b - b

Or the recent famous debate about returning Maybe a vs. Monad m = m a
for failure.

If we have seq' :: a - (), then we have

seq = m . seq'
  where m () = id

And of course we can go the other way too.

So it is a question of taste.  deepseq is simpler by at least two
standards: it is not polymorphic and it has only one argument.  There
are exactly two values of both () and forall b. b - b, but that fact
is more obvious of the former (IMO).  I think it is the right choice.

Luke
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: ANNOUNCE: deepseq-1.0.0.0

2009-11-17 Thread Malcolm Wallace
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

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe