One odd thing about the Haskell community is that we don’t use debuggers. We don’t even use stack traces. I think for several reasons:
It’s at least my experience that when my Haskell code goes wrong, I don’t fret too much because I put my code into small functions. If something’s not working as expected then I run that function in GHCi with typical inputs and check that the result is as desired.
If I’m in a codebase that makes it hard to do that, then I’ll insert some
trace calls and re-run the whole program.
It’s also my experience that I don’t care about GHCi’s debugging support if I have to manually set breakpoints myself and step through things manually. Who wants to bother doing that? It’s like running git commands manually instead of using magit.
So, I thought, as an experiment, I’d whip up a simple magit-like interface to GHCi’s debugging facilities, based upon my (limited) understanding from the manual and the tutorials about it, which should help me answer the following questions:
By removing the “it’s hard to use” impedance from the debugger, that puts me in a good position to evaluate the above questions. Is it that we as a community are missing out on sweet tooling because we just don’t have a convenient way to use it?
Here is a video demonstrating a trivial usage of it, i.e. the one that I’ve been testing with. I was too lazy to commentate it, but you can pause the video to see the display. I just set a breakpoint on
fib and step into the
main function and keep stepping until evaluation is complete. At one point I go to the REPL to inspect the local binding
x and then go back to stepping.
In the display you can see the current expression being evaluated, and the values of the local bindings and their types below. I think there’s room for in-place expansion of values, here. But I need to experiment with more interesting data structures.
I invite overenthusiastic early adopters to try pulling from the haskell-mode repo to play around with it and patch up obvious deficiencies. You have to be using haskell-interactive-mode’s REPL,
(require 'haskell-debug) and then run
M-x haskell-debug from a Haskell file or the REPL, like I do in the video. The rest should be fairly obvious from the buffer’s helpful messages. But if it doesn’t work as you expected because I don’t know the first thing about how debuggers are supposed to be used, don’t blame me. Just fix it.
I’m completely ambivalent about whether a debugger is really useful, I’ve never really used one properly. So I’ll try to use it to solve some problems—once I can find some decent use-cases—and report back in a few weeks. For science!