[GHC] #10160: GHCi :sprint has odd/unhelpful behavior for values defined within the REPL

GHC ghc-devs at haskell.org
Thu Mar 19 05:13:22 UTC 2015


#10160: GHCi :sprint has odd/unhelpful behavior for values defined within the REPL
-------------------------------------+-------------------------------------
        Reporter:  bitemyapp         |                   Owner:
            Type:  bug               |                  Status:  new
        Priority:  normal            |               Milestone:
       Component:  GHCi              |                 Version:  7.8.4
      Resolution:                    |                Keywords:  :sprint
Operating System:  Unknown/Multiple  |  thunk evaluation non-strictness
 Type of failure:  Incorrect result  |  laziness runtime ghci repl
  at runtime                         |            Architecture:
      Blocked By:                    |  Unknown/Multiple
 Related Tickets:                    |               Test Case:
                                     |                Blocking:
                                     |  Differential Revisions:
-------------------------------------+-------------------------------------

Comment (by rwbarton):

 Well to start with, none of this is really "behavior of `:sprint`": it's
 the behavior of ghci when interpreting expressions, and the details of
 this behavior are exposed by `:sprint`.

 Specifically, constructors are always fully applied in Core, so when ghci
 encounters a constructor application, it can (emit code to) directly
 produce a heap object representing an evaluated constructor, rather than
 producing whatever sort of heap object represents the application of an
 unknown function and leaving it to be reduced to WHNF later.

 I imagine that similar comments would apply to the case of integer
 literals at type `Integer`, where ghci should just build the required
 `Integer` literal directly rather than building a thunk for an application
 of `fromInteger` (whose argument would be exactly the necessary `Integer`
 literal anyways).

 Yes, this is done for performance reasons, but it's a more basic sort of
 thing than GHC's optimization passes. It would be quite poor for ghci not
 to work this way.

 I think this answers your question 1. As for 2 and 3, I don't know about
 the details of loading code from a file. It could be that in your example
 `x` is initially bound in ghci to something along the lines of `loadSymbol
 "Main.x"`, though I am just speculating based on your experiments.

 You might consider using an enumeration `let x = [1..3 :: Integer]`, which
 would behave a bit more like you expect, though forcing elements of that
 list will also cause earlier elements to be evaluated. I'm sure you can
 cook up a workaround for that if necessary.

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


More information about the ghc-tickets mailing list