[Haskell] modern language design, stone age tools

Alastair Reid alastair at reid-hoffmann.net
Wed Jun 23 07:11:11 EDT 2004

MR K P SCHUPKE <k.schupke at imperial.ac.uk> writes:
> You either end up single stepping through a million lines of code,
> or you find the error is of a complex non-localised kind anyway.

Or you find that inserting a breakpoint (or waiting to hit an exception), 
examining data structures which are either in scope or in the scope of the 
callers(*) tells you exactly what has gone wrong.  When writing in other 
languages, I find this is the most common scenario - though, of course, it is 
the non-localised heisenbugs that I remember most vividly.

* By 'callers' I mean the code that contains the application of the function 
to an argument not the code that first forced evaluation of the resulting 
application node.  For example, if I have 'let f x = (x+1,x-1) in fst(f 3)', 
then the caller of + is f not fst or the entire expression.

> I find inserting my own debug code into an application to be a much
> more fruitful way of keeping track of errors.

Unless, of course, you have:

1) A large program operating on a large body of data that takes a long time to 
hit the bug.

2) A bug that only shows up some of the time and the program is interactive 
which makes it hard (or tedious) to repeat the bug.

3) A complex library written by someone else which contains a bug or makes 
assumptions about the arguments passed to it.

4) A division by 0, call to head, etc. where the resulting error message 
provides absolutely no guidance about where the error is in your 30,000 line 
program forcing you to grep for all uses of the offending operation both in 
your program and in any libraries it uses.

[I may have left out a few other scenarios where being able to investigate the 
problem interactively and without already knowing where to look and what to 
look for is useful.]

> The only problem with [inserting debugging code by hand] in Haskell is
> that you sometimes have to lift a function into the IO monad for
> debugging... 

I find the trace function works very well for this.  It's interactive 
debugging that I really miss.

Alastair Reid

More information about the Haskell mailing list