views:

790

answers:

6

I'm interested in what tools and methods are used for diagnosing flaws in large scale functional programs. What tools are useful? My current understanding is that 'printf' debugging (e.g. add logging and redeploy) is what is typically used.

If you've done debugging of a functional system what was different about it then debugging a system built with an OO or procedural language?

+3  A: 

My current job is to implement new features and support a large system implemented in ocaml and C#. Most of the "logic" is implemented in caml and the GUI and data access is in C#. The debugging techniques are pretty much as you describe lots of logging and assert to work out what's gone wrong.

Additionally we have a large number of unit tests, which are just caml scripts for testing the logic and help to spot any regression errors.

We also use continuous integration to check the build and run nightly test scripts, including some automated testing of the GUI though our "automation" style scripting interface.

I quite often use the C# debugger for debugging the C# portion of the application, the ocaml debugger does yet work under windows so we don't use it. Although we hope one day we may fix this but it isn't top of our priority list. I have occasionally used windbg to investigate managed and unmanaged memory problems, though this turned out to be caused by a third party component implemented in C#.

So overall, nothing out of the ordinary but it seems to work okay, we don't see too many production problems.

Thanks, Rob

Robert
+8  A: 

Sadly, printf debugging seems to be the state of practice for Standard ML, Objective Caml, and Haskell. There's a little bit of debugging at the interactive read-eval-print loop, but once your app hits 25,000 or 50,000 lines that's less useful.

If you're lucky enough to be using Haskell, there's an exception: QuickCheck is indispensible for testing and deubgging. QuickCheck can be used even on combinations of Haskell and C code, as demonstrated by experience with the Xmonad window manager.

It's worth noting that around 1990 Andrew Tolmach built a very nice time-travel debugger for Standard ML of New Jersey, but that it was not considered worth maintaining. It's also worth noting that at one point the OCaml debugger (also a time-travel debugger) worked only on bytecode, which was inconvneient, and refused to violate abstraction barriers, which made it useless. This was around release 3.07 or so; perhaps things have improved.

Also in the early 1990s, Henrik Nilsson built an interesting debugger for Haskell, but mostly what it did was prevent the debugger from accidentally changing the evaluation behavior of the program. This was interesting, but only to lavzy-evaluation weenies.

As someone who has built or worked on large applications in all three of these languages, I find the state of play depressing.

Norman Ramsey
Interesting... what kind of bugs did you have in your applications, BTW? For the simple programs I write, I find it very hard to introduce bugs when coding in Haskell :)
ShreevatsaR
Oh, the last really exciting one was when I broke GHC's code generator by using the live variables of `e1` where I should have used `e2`. One character wrong, took a full day to find. GHC is, um, somewhat lacking in unit tests :-)
Norman Ramsey
+1  A: 

A couple of years ago when I did this I had to use a combination of printf debugging and QuickCheck. These days I would also use the ghci built-in debugger.

The biggest headache was actually laziness causing space-time leaks. There still doesn't seem to be a good answer to these: just do lots of profiling and keep trying to figure it out.

Paul Johnson
+2  A: 

F# has Visual Studio integration, so you can attach the debugger to your program and set breakpoints, watches, etc, just like with any other .NET language.

However, I prefer to avoid debugging as much as possible, by writing short functions that I can unit-test individually.

Mauricio Scheffer
A: 

OCaml and F# both have excellent debuggers. OCaml's is time reversible. F#'s has excellent IDE and multithreading support.

Jon Harrop
+4  A: 

The main tools we use at work (a Haskell shop) are:

  1. QuickCheck
  2. HPC: visual Haskell program coverage tool (we developed this in house)
  3. Logging/printf/trace
  4. Sometimes, the GHCi debugger
Don Stewart