[Solved]Why `:sprint` always print `_` even if the value has been evlauated?

I started reading Mr.Simon’s Parallel and Concurrent Programming in Haskell today.In the chapter 2.1,it gave examples of lazy evaluation:

ghci> let x = 1 + 2
ghci> :sprint x
x = _
ghci> x
3
ghci> :sprint x
x = 3

But when I try in GHCi, version 9.2.8,only get:

ghci> let x = 1 + 2
ghci> :sprint x
x = _
ghci> x
3
ghci> :sprint x
x = _
ghci> seq x 2
2
ghci> :sprint x
x = _

Has ghci changed the behavior of :sprint?Could someone give me some explanation of the reasons for it?

2 Likes

This is because numbers are overloaded. Try adding a type signature with a concrete type (and the book does do that):

ghci> let x = 1 + 2 :: Int
ghci> :sprint x
x = _
ghci> x
3
ghci> :sprint x
x = 3

That is because the overloaded version will basically be compiled to a function call, as if you had written this:

ghci> let x add = add 1 2
ghci> x (+)
3
ghci> :sprint x
x = _
4 Likes

Ah,thansk.It’s my bad.

Don’t feel bad, I think the current behavior of :sprint is definitely unintuitive, if you don’t already know how the evaluation of overloaded values are handled. IIRC during his talk at ZuriHac 2023 @kosmikus suggested that :sprint should ideally print closures and thunks in two distinct ways. There is a relevant ticket in GHC’s issue tracker. I tried to tackle it during ZuriHac and put up a draft PR that I unfortunately couldn’t spend enough time on to push it to finalization. Hopefully I’ll return back to it sometime soon :slight_smile:

7 Likes

Wow!Thanks for your additional explanation!:smiling_face_with_three_hearts:That’s really a truly valuable feature to add.
Best of luck with your efforts, and I hope you’ll be able to return to it soon.

4 Likes