[GHC] #14002: Defining a function in GHCi results in different strictness behavior than defining it in a file

GHC ghc-devs at haskell.org
Fri Jul 21 16:40:03 UTC 2017


#14002: Defining a function in GHCi results in different strictness behavior than
defining it in a file
-------------------------------------+-------------------------------------
        Reporter:  cocreature        |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.0.1
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 If you use `-fpedantic-bottoms` you get the behaviour you expect.

 This is all discussed in `CoreArity`, reproduced below.  It's not great,
 but I don't know how to fix it without imposing an unacceptable
 performance penalty.
 {{{
 Note [Dealing with bottom]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 A Big Deal with computing arities is expressions like

    f = \x -> case x of
                True  -> \s -> e1
                False -> \s -> e2

 This happens all the time when f :: Bool -> IO ()
 In this case we do eta-expand, in order to get that \s to the
 top, and give f arity 2.

 This isn't really right in the presence of seq.  Consider
         (f bot) `seq` 1

 This should diverge!  But if we eta-expand, it won't.  We ignore this
 "problem" (unless -fpedantic-bottoms is on), because being scrupulous
 would lose an important transformation for many programs. (See
 Trac #5587 for an example.)

 Consider also
         f = \x -> error "foo"
 Here, arity 1 is fine.  But if it is
         f = \x -> case x of
                         True  -> error "foo"
                         False -> \y -> x+y
 then we want to get arity 2.  Technically, this isn't quite right, because
         (f True) `seq` 1
 should diverge, but it'll converge if we eta-expand f.  Nevertheless, we
 do so; it improves some programs significantly, and increasing convergence
 isn't a bad thing.  Hence the ABot/ATop in ArityType.

 So these two transformations aren't always the Right Thing, and we
 have several tickets reporting unexpected behaviour resulting from
 this transformation.  So we try to limit it as much as possible:

  (1) Do NOT move a lambda outside a known-bottom case expression
        case undefined of { (a,b) -> \y -> e }
      This showed up in Trac #5557

  (2) Do NOT move a lambda outside a case if all the branches of
      the case are known to return bottom.
         case x of { (a,b) -> \y -> error "urk" }
      This case is less important, but the idea is that if the fn is
      going to diverge eventually anyway then getting the best arity
      isn't an issue, so we might as well play safe

  (3) Do NOT move a lambda outside a case unless
      (a) The scrutinee is ok-for-speculation, or
      (b) more liberally: the scrutinee is cheap (e.g. a variable), and
          -fpedantic-bottoms is not enforced (see Trac #2915 for an
 example)

 Of course both (1) and (2) are readily defeated by disguising the bottoms.
 }}}

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


More information about the ghc-tickets mailing list