[GHC] #11601: Strict Haskell is not as strict as it probably should be

GHC ghc-devs at haskell.org
Thu Feb 18 10:58:24 UTC 2016


#11601: Strict Haskell is not as strict as it probably should be
-------------------------------------+-------------------------------------
           Reporter:  simonpj        |             Owner:
               Type:  bug            |            Status:  new
           Priority:  normal         |         Milestone:
          Component:  Compiler       |           Version:  7.10.3
           Keywords:                 |  Operating System:  Unknown/Multiple
       Architecture:                 |   Type of failure:  None/Unknown
  Unknown/Multiple                   |
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 Consider this with `-XStrict`
 {{{
 f y = let Just x = blah[y] in body[y,x]
 }}}
 Suppose that in a call to `f`,
  * `blah` returns `Nothing`
  * but `body` does not use `x`
 Should `f` succeed?  For sure, `blah` will be evaluated to HNF before
 `body` is started, but is the match against `Just` done strictly too?

 According to [http://downloads.haskell.org/~ghc/master/users-
 guide/glasgow_exts.html#recursive-and-polymorphic-let-bindings our current
 semantics], in the match against `Just` is ''not'' done strictly, so the
 call should succeed.  I think that’s unexpected and probably wrong.

 The translation goes like this:
 {{{
               !(Just x) = blah
 ==> (FORCE)   v = blah; Just x = v    (and add a seq on v)
 ==> (SPLIT)   v = blah; x = case v of Just x -> x
 }}}
 So we finish up with
 {{{
 f y = let v = blah[y] in
       let x = case v of Just x -> x in
       v `seq` body[y,x]
 }}}
 I don’t think that’s what we intended, because there's a thunk for `x`.
 If the pattern can fail, I think we want the FORCE rule to say this:
 {{{
 Replace any binding !p = e with
 v = case e of p -> (v1,..,vn); (v1,..,vn) = v
 and replace e0 with v seq e0,
 where v is fresh and v1..vn are the variable(s) bound by p
 }}}
 (Compare with the text at the above link.)

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11601>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list