I have been so busy working and coding that I completely forgot about my blog. That, or that I hate blogging. This is something that puzzles me. I love reading blogs, I know that. I especially love good writers, so maybe it's a problem of fear of comparison. Steve Yegge is a great writer. Much better than Paul Graham -I won't say sorry Steve, I know he is not reading this- . I especially dearly love the witches one, it reminds me of House. I've also been watching House a lot lately. Much better than the over hyped Lost or Prison Break if you ask me.
But honestly, during this month I've been doing some work too. I have actually managed to put up some patches -sorry, you missed my 'first patch' post- and to get myself exposed in the public -you missed that one too-. Don't worry, it is all neatly included in a very nice page at the haskell wiki.
That last part is actually interesting. If you don't mind, since it took me a few minutes to compose it, I am going to call the holy powers of reuse and paste a nice info bit about the closure viewer from there.
Currently it provides two new commands under ghci, :print and :sprint, both used in the same way as :type or :info. The latter prints a semievaluated closure using underscores to represent suspended computations (pretty much as [[Hood]] does). The former one in addition binds these thunks to variable names, so that you can do things with them.
Example:
Prelude> let li = map Just [1..5]
Prelude> length li
5
Prelude> :sp li
li - _:_:_:_:_:[]
Prelude> head li
Just 1
Prelude> :sp li
li - Just 1:_:_:_:_:[]
Prelude> last li
Just 5
Prelude> :sp li
li - Just 1:_:_:_:Just 5:[]
Prelude> :p li
li - Just 1 : (_t987::Maybe Integer) : (_t988::Maybe Integer) : (_t989::Maybe Integer) : [Just 5]
Prelude> _t987 `seq` ()
Prelude> :p li
li - Just 1 : Just 2 : (_t457::Maybe Integer) : (_t458::Maybe Integer) : [Just 5]
Prelude> _t988
Just 3
Its best feature is that it can work without type information, so you can display polymorphic objects the type of which you don't know. However if there is type information available, it is used. It could be made totally independent of type info, so that it could work with opaque or coerced (wrong) types. For instance:
data Opaque = forall a. O a
*Test2> let li = map Just [1..5]
*Test2> let o = O li
*Test2> head li `seq` ()
*Test2> length li `seq` ()
*Test2> :p o
o - O Just 1 : (_t126::a) : (_t125::a) : (_t124::a) : (_t123::a) : []
In the example above the li inside o is not typed, so the bindings aren't either. However, it would be possible to extend the closure viewer so that it recovers its types.
Other currently proposed extensions are a safeCoerce function (not so useful, it depends on ghc-api) and an unsafeDeepSeq (this one is decoupled from ghc-api). There is also a generally useful (for compiler/tool developers) isFullyEvaluated query function. The signatures being:
isFullyEvaluated :: a -> IO Bool
unsafeDeepSeq :: a -> b -> b
safeCoerce :: GHC.Session -> a -> Maybe b
That's all for this one. Some of you people have been annoyed that my feeds are not working. Don't worry, I will be fixing them soon.