seq#: do we actually need it as a primitive?

I've read about the inlining issues surrounding Control.Exception.evaluate that seem to have prompted the creation of seq#, but I'm still missing something. Isn't seq# a s the same as let !a' = a in (# s, a' #) ? David

For posterity, the answer is no, and it is explained in this comment: https://ghc.haskell.org/trac/ghc/ticket/5129#comment:2 Edward Excerpts from David Feuer's message of 2015-01-07 11:12:55 -0800:
I've read about the inlining issues surrounding Control.Exception.evaluate that seem to have prompted the creation of seq#, but I'm still missing something. Isn't seq# a s the same as let !a' = a in (# s, a' #) ?
David

On 08/01/15 10:00, Edward Z. Yang wrote:
For posterity, the answer is no, and it is explained in this comment: https://ghc.haskell.org/trac/ghc/ticket/5129#comment:2
Thanks, this is helpful. So we have three potential implementations for evaluate: (1) \x -> return $! x (2) \x -> (return $! x) >>= return (3) implemented using seq# (1) and (2) are supposed to be equivalent (by the monad law), but are not in reality, since in (2) evaluate x is always a value. The documentation for 'evaluate' talks about the difference between (1) and (2). Furthermore, it suggests that (2) is a valid implementation. (1) is buggy, as explained in #5129 linked above. However, it doesn't say anything about (2). Would (2) still suffer from #5129? In that case, the docs should be fixed. Also, where can I find the 'instance Monad IO' as understood by GHC? grep didn't find one. Roman

No (2) would not suffer from #5129. Think of type IO a = State# -> (State#, a) return x = \s -> (s, x) (>>=) m k s = case m s of (s, r) -> k r s (it's a newtype actually, but this will do here). (2) says = \x -> (return $! x) >>= return = \x. \s. case return $! x s of (s1, r) -> return r s1 = \x\s. x `seq` case (s,x) of (s1, r) -> return r s1 = \x\s. x `seq` (s,x) which is fine. Simon | -----Original Message----- | From: ghc-devs [mailto:ghc-devs-bounces@haskell.org] On Behalf Of | Roman Cheplyaka | Sent: 08 January 2015 13:42 | To: Edward Z. Yang; David Feuer | Cc: ghc-devs | Subject: Re: seq#: do we actually need it as a primitive? | | On 08/01/15 10:00, Edward Z. Yang wrote: | > For posterity, the answer is no, and it is explained in this | comment: | > https://ghc.haskell.org/trac/ghc/ticket/5129#comment:2 | | Thanks, this is helpful. | | So we have three potential implementations for evaluate: | | (1) \x -> return $! x | (2) \x -> (return $! x) >>= return | (3) implemented using seq# | | (1) and (2) are supposed to be equivalent (by the monad law), but are | not in reality, since in (2) evaluate x is always a value. | | The documentation for 'evaluate' talks about the difference between | (1) and (2). Furthermore, it suggests that (2) is a valid | implementation. | | (1) is buggy, as explained in #5129 linked above. However, it doesn't | say anything about (2). | | Would (2) still suffer from #5129? In that case, the docs should be | fixed. | | Also, where can I find the 'instance Monad IO' as understood by GHC? | grep didn't find one. | | Roman | _______________________________________________ | ghc-devs mailing list | ghc-devs@haskell.org | http://www.haskell.org/mailman/listinfo/ghc-devs

Then why was the primop introduced? On 08/01/15 17:05, Simon Peyton Jones wrote:
No (2) would not suffer from #5129. Think of
type IO a = State# -> (State#, a) return x = \s -> (s, x) (>>=) m k s = case m s of (s, r) -> k r s
(it's a newtype actually, but this will do here).
(2) says
= \x -> (return $! x) >>= return = \x. \s. case return $! x s of (s1, r) -> return r s1 = \x\s. x `seq` case (s,x) of (s1, r) -> return r s1 = \x\s. x `seq` (s,x)
which is fine.
Simon
| -----Original Message----- | From: ghc-devs [mailto:ghc-devs-bounces@haskell.org] On Behalf Of | Roman Cheplyaka | Sent: 08 January 2015 13:42 | To: Edward Z. Yang; David Feuer | Cc: ghc-devs | Subject: Re: seq#: do we actually need it as a primitive? | | On 08/01/15 10:00, Edward Z. Yang wrote: | > For posterity, the answer is no, and it is explained in this | comment: | > https://ghc.haskell.org/trac/ghc/ticket/5129#comment:2 | | Thanks, this is helpful. | | So we have three potential implementations for evaluate: | | (1) \x -> return $! x | (2) \x -> (return $! x) >>= return | (3) implemented using seq# | | (1) and (2) are supposed to be equivalent (by the monad law), but are | not in reality, since in (2) evaluate x is always a value. | | The documentation for 'evaluate' talks about the difference between | (1) and (2). Furthermore, it suggests that (2) is a valid | implementation. | | (1) is buggy, as explained in #5129 linked above. However, it doesn't | say anything about (2). | | Would (2) still suffer from #5129? In that case, the docs should be | fixed. | | Also, where can I find the 'instance Monad IO' as understood by GHC? | grep didn't find one. | | Roman | _______________________________________________ | ghc-devs mailing list | ghc-devs@haskell.org | http://www.haskell.org/mailman/listinfo/ghc-devs

I was wrong. See https://ghc.haskell.org/trac/ghc/ticket/5129#comment:17 which I have just added. Simon | -----Original Message----- | From: Simon Peyton Jones | Sent: 08 January 2015 15:05 | To: 'Roman Cheplyaka'; Edward Z. Yang; David Feuer | Cc: ghc-devs | Subject: RE: seq#: do we actually need it as a primitive? | | No (2) would not suffer from #5129. Think of | | type IO a = State# -> (State#, a) | return x = \s -> (s, x) | (>>=) m k s = case m s of (s, r) -> k r s | | (it's a newtype actually, but this will do here). | | (2) says | | = \x -> (return $! x) >>= return | = \x. \s. case return $! x s of (s1, r) -> return r s1 | = \x\s. x `seq` case (s,x) of (s1, r) -> return r s1 | = \x\s. x `seq` (s,x) | | which is fine.

I made an attempt at a better documentation for evaluate. See here: https://phabricator.haskell.org/D615

On Sun, Jan 11, 2015 at 9:25 PM, Roman Cheplyaka
I made an attempt at a better documentation for evaluate. See here: https://phabricator.haskell.org/D615
Wunderbar. I especially liked the prescription at the end on when to use evaluate and when to prefer (return $!). -- Kim-Ee
participants (5)
-
David Feuer
-
Edward Z. Yang
-
Kim-Ee Yeoh
-
Roman Cheplyaka
-
Simon Peyton Jones