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

GHC ghc-devs at haskell.org
Sun Mar 15 06:23:55 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
              Keywords:  :sprint     |  Operating System:  Unknown/Multiple
  thunk evaluation                   |   Type of failure:  Incorrect result
          Architecture:              |  at runtime
  Unknown/Multiple                   |        Blocked By:
             Test Case:              |   Related Tickets:
              Blocking:              |
Differential Revisions:              |
-------------------------------------+-------------------------------------
 Wanted to use :sprint to help learners visualise thunk evaluation behavior
 in their data. Ran into some behaviors that a few people I checked with
 didn't have a good explanation for. I couldn't find anything in the user
 guide to explain this. I don't think it technically violates Haskell
 Report requirements, but it makes :sprint considerably less useful if
 you're teaching somebody non-strictness.

 Examples with code in the REPL:

 {{{
 Prelude> let x = [1, 2, 3]
 Prelude> :sprint x
 x = _
 Prelude> :t x
 x :: Num t => [t]
 -- this makes sense so far.

 Prelude> let x = [1, 2, 3 :: Integer]
 Prelude> :sprint x
 x = [1,2,3]
 -- errr, what?

 Prelude> let x = Just (1 :: Integer)
 Prelude> :sprint x
 x = Just 1

 Prelude> let just = Just
 Prelude> let x = just (1 :: Integer)
 Prelude> :sprint x
 x = _

 Prelude> let x = Just (undefined :: Integer)
 Prelude> :sprint x
 x = Just _

 Prelude> let x = just (undefined :: Integer)
 Prelude> :sprint x
 x = _

 Prelude> let x = [1, 2, 3 :: Integer]
 Prelude> let y = x
 Prelude> :sprint y
 y = [1,2,3]

 Prelude> let x = 1 : 2 : (3 :: Integer) : []
 Prelude> :sprint x
 x = [1,2,3]
 Prelude> let x = [1] ++ [2] ++ [(3 :: Integer)]
 Prelude> :sprint x
 x = _

 Prelude> let y = (:)
 Prelude> let x = 1 `y` (2 `y` ((3 :: Integer) `y` []))
 Prelude> :sprint x
 x = _
 Prelude> x
 [1,2,3]
 Prelude> :sprint x
 x = [1,2,3]
 }}}

 So the behavior here seems to be:

 Constructors used directly in the construction of data and are not passed
 functions (including polymorphic vals awaiting concrete instances)/bottoms
 are immediately evaluated

 Example, but with loading data from a file:

 Contents of the file:

 {{{
 x :: Num a => [a]
 x = [1, 2, 3]
 }}}

 GHCi session:

 {{{
 Prelude> :t x
 x :: Num a => [a]

 Prelude> :sprint x
 x = _

 Prelude> x
 [1,2,3]

 Prelude> :sprint x
 x = _
 }}}

 Then when x is loaded from a file, but has a different type:

 {{{
 Prelude> :t x
 x :: [Integer]
 Prelude> :sprint x
 x = _
 Prelude> head x
 1
 Prelude> :sprint x
 x = [1,2,3]
 }}}

 Now, this is a bit confusing. Earlier I was able to get :sprint to return
 [1, _, _] when I evaluated head x, but a couple hours later when I went to
 write this ticket, I couldn't reproduce that behavior.

 Is there documentation that explains:

 1. Why data is shown as having been evaluated at time of declaration
 (seemingly) by :sprint when it's defined in the GHCi

 2. Why declaring code in GHCi and loading it from a file behaves
 differently with :sprint (I considered let expression in the implicit GHCi
 do-block...couldn't find anything to explain this)

 3. Why evaluating 'head x' forces the other values as well

 Are any of these behaviors a bug? If not, are they documented anywhere? Is
 the "eager" treatment of constructors in GHCi a performance thing? That
 seems strange given I didn't have -fobject-code turned on.

 :sprint not demonstrating semantics that match what I expect from a non-
 strict language hinders its utility as a teaching tool and means the only
 robust option for learners that I can find is testing evaluation with
 bottom values.

 {{{
 -- So that you know i picked "7.8.4" as the version consciously

 [callen at atlantis ~/Work/fpbook]$ ghc --version
 The Glorious Glasgow Haskell Compilation System, version 7.8.4

 [callen at atlantis ~/Work/fpbook]$ ghci --version
 The Glorious Glasgow Haskell Compilation System, version 7.8.4
 }}}

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


More information about the ghc-tickets mailing list