Hi,
I get the impression that blogs and planet.haskell.org are the best way
to disseminate information about new tools any more. Maybe a part of the
earlier importance has been taken over by GooglePlus, but not all,
leaving both blogs and GooglePlus less useful individually?
Anyways, I’d like to tell you about a feature of ghc-heap-view that I
have blogged about¹, namely the possibility to inspect heap values
recursively in GHCi or in your programs, including thunks, the
references between them and sharing:
Prelude :script /home/jojo/.cabal/share/ghc-heap-view-0.4.0.0/ghci
Prelude let x = [1..10]
Prelude x
[1,2,3,4,5,6,7,8,9,10]
Prelude :printHeap x
_bh [S# 1,S# 2,S# 3,S# 4,S# 5,S# 6,S# 7,S# 8,S# 9,S# 10]
Note that the tools shows us that the list is a list of S# constructors,
and also that it is still hidden behind a blackhole. After running
System.Mem.performGC, this would disappear.
Prelude let x = Just (1 + 1)
Prelude :printHeap x
Just _bco
Prelude x
Just 2
Prelude System.Mem.performGC
Prelude :printHeap x
Just (S# 2)
Here, we see how the calculation was deferred until forced by showing
the value of x. The name _bco stands for a bytecode object as used by
the interpreter. Getting useful information from them is a bit harder
than for compiled thunks, so for more accurate results put the code in a
Haskell source file, compile it and use the GHC.HeapView API to print
the interesting parts.
Prelude let a = hi
Prelude let partial = (a ++)
Prelude partial
hi
Prelude System.Mem.performGC
Prelude let x = (a, partial)
Prelude :printHeap x
let x1 = hi
in (x1,_fun x1)
This demonstrates a partial application. The information which function
is called there (++ in this case) is lost at runtime, but we still see
that the second element of the tuple is a partial application of some
value to the first element.
Prelude let s = ho
Prelude let x = cycle s
Prelude length (take 100 (show x))
100
Prelude System.Mem.performGC
Prelude :printHeap x
let x0 = C# 'h' : C# 'o' : x0
in x0
Prelude let y = map Data.Char.toUpper x
Prelude length (take 100 (show y))
100
Prelude :printHeap y
C# 'H' : C# 'O' : C# 'H' : C# 'O' : C# 'H' : C# 'O' : C# 'H' : C# 'O' : C# 'H'
: C# 'O' : _bh (C# 'H' : C# 'O' : C# 'H' : C# 'O' : C# 'H' : C# 'O' : C# 'H' :
C# 'O' : ... : ...)
The cyclic, tying-the-knot structure of cycle is very visible. But can
also see how easily it is broken, in this case by mapping a function
over the list.
Prelude let {x = 'H' : y ; y = 'o' : x }
Prelude length (show (take 10 x, take 10 y)) `seq` return ()
Prelude System.Mem.performGC
Prelude :printHeap (x,y)
let x1 = C# 'H' : x3
x3 = C# 'o' : x1
in (x1,x3)
If you want to look at multiple variables at once, just pass a tuple to
printHeap
I hope you’ll find it useful, and I am happy to hear about other
features that you might be interested in.
Also, if you don’t know about it, a graphical and interactive variant of
this is available as ghc-vis².
Greetings,
Joachim
¹
http://www.joachim-breitner.de/blog/archives/580-GHCi-integration-for-GHC.HeapView.html
² http://felsin9.de/nnis/ghc-vis/
--
Joachim nomeata Breitner
m...@joachim-breitner.de | nome...@debian.org | GPG: 0x4743206C
xmpp: nome...@joachim-breitner.de | http://www.joachim-breitner.de/
signature.asc
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe