Sunday, December 17, 2017

Announcing the 'debug' package

Haskell is a great language, but debugging Haskell is undoubtedly a weak spot. To help with that problem, I've just released the debug library. This library is intended to be simple and easy to use for a common class of debugging tasks, without solving everything. As an example, let's take a function we are interested in debugging, e.g.:

module QuickSort(quicksort) where
import Data.List

quicksort :: Ord a => [a] -> [a]
quicksort [] = []
quicksort (x:xs) = quicksort lt ++ [x] ++ quicksort gt
    where (lt, gt) = partition (<= x) xs

Turn on the TemplateHaskell and ViewPatterns extensions, import Debug, indent your code and place it under a call to debug, e.g.:

{-# LANGUAGE TemplateHaskell, ViewPatterns #-}
module QuickSort(quicksort) where
import Data.List
import Debug

debug [d|
   quicksort :: Ord a => [a] -> [a]
   quicksort [] = []
   quicksort (x:xs) = quicksort lt ++ [x] ++ quicksort gt
       where (lt, gt) = partition (<= x) xs
   |]

We can now run our debugger with:

$ ghci QuickSort.hs
GHCi, version 8.2.1: http://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling QuickSort        ( QuickSort.hs, interpreted )
Ok, 1 module loaded.
*QuickSort> quicksort "haskell"
"aehklls"
*QuickSort> debugView

The call to debugView starts a web browser to view the recorded information, looking something like:

From there you can click around to explore the computation.

I'm interested in experiences using debug, and also have a lot of ideas for how to improve it, so feedback or offers of help most welcome at the bug tracker.

If you're interested in alternative debuggers for Haskell, you should check out the GHCi debugger or Hood/Hoed.

12 comments:

Francesco said...

Excellent functional present for Christmas.
I toyed with it a bit and it is just what I badly needed a week ago. Well done!

note: `debugView` crashed on with "permission Denied" (I had to invoke firefox manually in /tmp/somefile). The machine I am working on at the moment is a bit messed up, so I am not sure if the problem lies here on in `debug`.

λ> debugView
/bin/sh: 1: /tmp/debug15031-0.html: Permission denied
*** Exception: Failed when running system command: /tmp/debug15031-0.html
CallStack (from HasCallStack):
error, called at src/System/Process/Extra.hs:34:9 in extra-1.6.2-71408fb500ae41da55329b03b6416e1ca9b2f879472eb20eca68e457ec23417c:System.Process.Extra
system_, called at src/Debug/Record.hs:127:5 in debug-0.0-ba453cdfd2d26dedd6753b914f3e6d1bf79a012a44fd5e3a82fabda1e033054b:Debug.Record

Neil Mitchell said...

Francesco: I suspect it doesn’t work on Linux. How would you launch and HTML page on Linux with Haskell?

Neil Mitchell said...

Francesco: I just released 0.0.1 - can you give it a whirl and let me know? Should now work on Linux and Mac, as well as Windows.

CLF said...

Can you use xdg-open to open a browser on Linux?

Neil Mitchell said...

CLF: I used open-browser which does the right thing on every OS, including xdg-open on Linux

CLF said...

@Neil: nice! I learned something today :)

Francesco said...

Hello Neil, still no dice

λ> quicksort "haskell"
"aehklls"
λ> debugView
wine: invalid directory "/home/f/.wine" in WINEPREFIX: not an absolute path

`λ> openBrowser "http://www.haskell.org"` works though.

Neil Mitchell said...

what about openBrowser on an absolute file path? Should I be doing the file:/// prefix myself?

Florian said...

Seems like Francescos xdg-open is handled by wine. Had this once on my laptop and don't remember how to fix it. But I assume the debug library is not at fault there.

Francesco said...

@Neil: Yup, what Florian said is correct. I fixed my system and now `debugView` runs fine!

Neil Mitchell said...

Awesome! I just confirmed on my Linux VM and it works fine. I added an entry to the FAQ at https://github.com/ndmitchell/debug/blob/master/README.md#q-debugview-fails-talking-about-wine. If you have a link describing what you can do to fix the problem I'll include that too.

atc said...

What a fantastic idea & implementation. I'll use it in anger! Merry xmas & a happy new year!