Friday, September 22, 2006

The ICFP contest has a winner!



And no, this year Haskell is not the language of choice :(

Don't miss the video of the presentation at ICFP, seriously cool stuff, at least if you can follow the geeky -rather academia- jokes. Only by watching it you'll find out which is the super-cool multinational company that has conquered both 1st and 3rd prize this year.

#haskell managed to have 5 teams among the first 50: Lazy Bottoms, DunComLooLump, Deus Ex Machina, Team Roflcopter, and the Int-E lone ranger team. Not too shabby, though nothing compared to previous successes. None of the winners this year used a high-level language.

By the way, a few weeks ago I made a video to showcase the ghci debugger which used the ICFP contest task as an example. Watch it!

Debugging in Haskell

Some few days ago, an innocent query sparkled a fiery discussion in the Haskell mailing list, this time about the virtues and vices of debugging.

At the time I did put up a quick survey page in the wiki about the various debugging options available in Haskell (including the ghci debugger, of course!), but I didn't think about mentioning it here. A partial rip-off of that page follows.

Printf and friends
The simplest approach is to use Debug.Trace.trace:
trace :: String -> a -> a
When called, trace outputs the string in its first argument, before returning the second argument as its result.

A common idiom to trace a function is:
myfun a b | trace ("myfun " ++ show a ++ " " ++ show b) False = undefined
myfun a b = ...
The advantage is that disabling and enabling the trace takes only one line comment.
You must keep in mind that due to lazy evaluation your traces will only print if the value they wrap is ever demanded.

A more powerful alternative for this approach is Hood. Even if it hasn't been updated in some time, Hood works perfectly with the current ghc distribution. Even more, Hugs has it already integrated, see the manual page. Add an import Observe and start inserting observations in your code.
For instance:
import Hugs.Observe

f' = observe "Informative name for f" f
f x = if odd x then x*2 else 0
And then in hugs:
Main> map f' [1..5]
[2,0,6,0,10]

>>>>>>> Observations <<<<<<> 10
, \ 4 -> 0
, \ 3 -> 6
, \ 2 -> 0
, \ 1 -> 2
}
The evaluation outputs a report of all the invocations of f and their result.

I have a handy bogus Hugs.Observe module with no-ops for the observations so that I don't need to remove them manually, expecting that the compiler will optimize them away.

Dynamic breakpoints in GHCi
Finally, the GHCi Debugger project aims to bring dynamic breakpoints and intermediate values observation to GHCi in a near future. Right now the tool is only available from the site as a modified version of GHC, so unfortunately you will have to compile it yourself if you want to have it.

This tool allows to set breakpoints in your code, directly from the GHCi command prompt. An example session:
*main:Main> :break add Main 2
Breakpoint set at (2,15)
*main:Main> qsort [10,9..1]
Local bindings in scope:
x :: a, xs :: [a], left :: [a], right :: [a]

qsort2.hs:2:15-46> :sprint x
x = _
qsort2.hs:2:15-46> x
This is an untyped, unevaluated computation. You can use seq to
force its evaluation and then :print to recover its type
qsort2.hs:2:15-46> seq x ()
()
qsort2.hs:2:15-46> :p x
x - 10
Once a breakpoint is hit, you can explore the bindings in scope, as well as to evaluate any haskell expression, as you would do in a normal GHCi prompt. The ':print' command can be very useful to explore the lazyness of your code.