[GHC] #16089: seq is not cooperating with :sprint in GHCi as expected

#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.6.3 Keywords: seq sprint | Operating System: Linux strictness | Architecture: | Type of failure: Incorrect result Unknown/Multiple | at runtime Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- I was playing around with strictness and performed following test: {{{#!hs Prelude> x = [True, False] Prelude> :sprint x x = _ Prelude> x `seq` True True Prelude> :sprint x x = _ }}} I completely don't understand why `x = _` at this moment. `seq` must evaluate one level of `x` achieving `x = True : _` to ensure that it is not `undefined`, so why is this information lost? I am testing it on GHCi version 8.6.3, but it is not reproducible on other versions (checked on 8.4.4, 8.2.2 and 7._._). I have asked about it on SO, so if this behavior is intended I kindly ask for explaination here [https://stackoverflow.com/questions/53898220 /sprint-and-seq-together-missing-evaluation] to let others know. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.6.3 Resolution: | Keywords: seq sprint | strictness Operating System: Linux | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by osa1): I can't reproduce this: {{{ GHCi, version 8.6.3: http://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/omer/rcbackup/.ghci λ:1> let x = [True, False] λ:2> :sprint x x = [True,False] }}} With 8.4.4: {{{ GHCi, version 8.4.4: http://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/omer/rcbackup/.ghci λ:1> let x = [True, False] λ:2> :sprint x x = [True,False] }}} With 8.2.2: {{{ GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/omer/rcbackup/.ghci λ:1> let x = [True, False] λ:2> :sprint x x = [True,False] }}} However if I use a list that is not completely static then I can see that `:sprint` doesn't print the evaluated constructor: {{{ GHCi, version 8.6.3: http://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/omer/rcbackup/.ghci λ:1> let x = [1..] λ:2> :sprint x x = _ λ:3> x `seq` () () λ:4> :sprint x x = _ }}} Even `:print` doesn't work as expected (I'd expect it to print something like `x : y`): {{{ λ:5> :print x x = (_t1::(Num a, Enum a) => [a]) }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

I can't reproduce this:
{{{ GHCi, version 8.6.3: http://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/omer/rcbackup/.ghci λ:1> let x = [True, False] λ:2> :sprint x x = [True,False] }}}
With 8.4.4:
{{{ GHCi, version 8.4.4: http://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/omer/rcbackup/.ghci λ:1> let x = [True, False] λ:2> :sprint x x = [True,False] }}}
With 8.2.2:
{{{ GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/omer/rcbackup/.ghci λ:1> let x = [True, False] λ:2> :sprint x x = [True,False] }}}
However if I use a list that is not completely static then I can see
#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.6.3 Resolution: | Keywords: seq sprint | strictness Operating System: Linux | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by radrow): Replying to [comment:1 osa1]: that `:sprint` doesn't print the evaluated constructor:
{{{ GHCi, version 8.6.3: http://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/omer/rcbackup/.ghci λ:1> let x = [1..] λ:2> :sprint x x = _ λ:3> x `seq` () () λ:4> :sprint x x = _ }}}
Even `:print` doesn't work as expected (I'd expect it to print something
like `x : y`):
{{{ λ:5> :print x x = (_t1::(Num a, Enum a) => [a]) }}}
Note that I am declaring `x` without `let` keyword. {{{ x = [True, False] }}} not {{{ let x = [True, False] }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.6.3 Resolution: | Keywords: seq sprint | strictness Operating System: Linux | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by dfeuer): I can verify that `let` actually makes a difference here. Curiouser and curiouser! -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.6.3 Resolution: | Keywords: seq sprint | strictness Operating System: Linux | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by dfeuer): * cc: dfeuer (added) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.6.3 Resolution: | Keywords: seq sprint | strictness Operating System: Linux | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by mpickering): I also observed there is some difference between `let x = 1` and `x = 1` whilst using `ghc-heap`. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.6.3 Resolution: | Keywords: seq sprint | strictness Operating System: Linux | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by radrow): `const True $! x` works as expected -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.6.3 Resolution: | Keywords: seq sprint | strictness Operating System: Linux | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): All very curious. The GHCi debugger, which is responsible for `:sprint` and friends, needs a love and attention, if anyone feels able to offer it. Its's tricky stuff, because it uses special primitives to interrogate the heap and decomposes heap objects, which never usually happens in Haskell. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.6.3 Resolution: | Keywords: seq sprint | strictness Operating System: Linux | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by osa1): I think there's another bug here which is that `let x = ...` and `x = ...` are supposed to be the same thing in GHCi, but they're currently not. I vaguely remember the ticket that requested supporting `x = ...` syntax in GHCi (without the `let`), but I don't remember how it was implemented. I guess there's a bug there and perhaps we should track it in another ticket. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.6.3 Resolution: | Keywords: seq sprint | strictness Operating System: Linux | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #7253 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by dfeuer): * related: => #7253 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.6.3 Resolution: | Keywords: seq sprint | strictness Operating System: Linux | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #7253 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by osa1): I did a little bit of digging. The only difference between `:sprint` and `:print` is that `:sprint` doesn't bind "suspensions". So sometimes you see a `_` with `:sprint`, but `:print` gives you a variable instead (see last two code snippets in comment:1). What is a "suspension"? `RtClosureInspect` has a simplistic view of Haskell runtime objects, and it treats these as "suspensions": - `BLACKHOLE`s that point to `TSO` or `BLOCKING_QUEUE`s (as expected, becuase these are thunks that are not evaluated yet) - Anything other than `MUT_VAR` and `CONSTR`s. When we do `:print x` what `RtClosureInspect` uses `ghc-heap` to inspect the value of `x` and sees an `AP` that looks like this: {{{ APClosure { info = StgInfoTable { entry = Nothing , ptrs = 0 , nptrs = 0 , tipe = AP , srtlen = 0 , code = Nothing } , arity = 709704 , n_args = 0 , fun = () <-- this is actually a `ForeignRef HValue`, but shown as () because we cna't show `ForeignRef`s , payload = [] } }}} which is probably a bug in `ghc-heap` because even if `x` is really an `AP` the `arity` field makes no sense (it should be 0). For reference, the BCOs generated for `x = [True,False]`: {{{ ProtoBCO x1_r1zt#0 []: GHC.Types.: @ GHC.Types.Bool GHC.Types.False (GHC.Types.[] @ GHC.Types.Bool) bitmap: 0 [] PUSH_G GHC.Types.[] PUSH_G GHC.Types.False PACK : 2 ENTER ProtoBCO Ghci1.x#0 []: GHC.Types.: @ GHC.Types.Bool GHC.Types.True x1_r1zt bitmap: 0 [] PUSH_G x1_r1zt PUSH_G GHC.Types.True PACK : 2 ENTER }}} BCO generated for `let x = [True,False]`: {{{ ProtoBCO ExprTopLevel_E0#0 []: let sat_s1yG = ... in ... bitmap: 0 [] PUSH_G GHC.Types.[] PUSH_G GHC.Types.False PACK : 2 PUSH_L 0 PUSH_G GHC.Types.True PACK : 2 PUSH_G GHC.Types.[] PUSH_L 1 PACK : 2 PUSH_L 0 PUSH_APPLY_P PUSH_G GHC.Base.returnIO SLIDE 3 3 ENTER }}} These should really be identical. For this I filed #16096. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.6.3 Resolution: | Keywords: seq sprint | strictness Operating System: Linux | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #7253, #16096 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by osa1): * related: #7253 => #7253, #16096 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.6.3 Resolution: | Keywords: seq sprint | strictness Operating System: Linux | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #7253, #16096 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by osa1): My fix for #16096 (Phab:D5473) fixes the original reproducer: {{{ ~ $ ghc-stage2 --interactive GHCi, version 8.7.20181227: https://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/omer/rcbackup/.ghci λ:1> x = [True, False] λ:2> :sprint x x = [True,False] λ:3> :print x x = [True,False] }}} Here's a slightly more complex example: {{{ ~ $ ghc-stage2 --interactive GHCi, version 8.7.20181227: https://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/omer/rcbackup/.ghci λ:1> x = [ 1.. ] :: [Integer] λ:2> :sprint x x = _ λ:3> x `seq` () () λ:4> :sprint x x = 1 : _ }}} However if I omit the type annotation in the first line it doesn't work as expected: {{{ ~ $ ghc-stage2 --interactive GHCi, version 8.7.20181227: https://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/omer/rcbackup/.ghci λ:1> x = [ 1.. ] λ:2> x `seq` () () λ:3> :sprint x x = _ }}} I'd expect to see the same output `x = 1 : _` here. We should use this one as the reproducer. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089#comment:12 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.6.3 Resolution: | Keywords: seq sprint | strictness Operating System: Linux | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #7253, #16096 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by dfeuer): No, the current behavior is fine when there's no type signature. GHCi turns off the monomorphism restriction by default, so `x :: Num a => [a]`. It's a function, not an updateable thunk. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089#comment:13 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.6.3 Resolution: | Keywords: seq sprint | strictness Operating System: Linux | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #7253, #16096 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by osa1): Ah, that makes sense. Indeed I can see that my last example works if I do `:set -XMonomorphismRestriction`, so perhaps Phab:D5473 closes this ticket too. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089#comment:14 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: patch Priority: normal | Milestone: Component: GHCi | Version: 8.6.3 Resolution: | Keywords: seq sprint | strictness Operating System: Linux | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #7253, #16096 | Differential Rev(s): MR:97 Wiki Page: | -------------------------------------+------------------------------------- Changes (by osa1): * status: new => patch * differential: => MR:97 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089#comment:15 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#16089: seq is not cooperating with :sprint in GHCi as expected -------------------------------------+------------------------------------- Reporter: radrow | Owner: (none) Type: bug | Status: closed Priority: normal | Milestone: 8.8.1 Component: GHCi | Version: 8.6.3 Resolution: fixed | Keywords: seq sprint | strictness Operating System: Linux | Architecture: | Unknown/Multiple Type of failure: Incorrect result | Test Case: at runtime | ghci/scripts/T16089 Blocked By: | Blocking: Related Tickets: #7253, #16096 | Differential Rev(s): MR:97 Wiki Page: | -------------------------------------+------------------------------------- Changes (by RyanGlScott): * testcase: => ghci/scripts/T16089 * status: patch => closed * resolution: => fixed * milestone: => 8.8.1 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16089#comment:16 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC