[Haskell] modern language design, stone age tools
S. Alexander Jacobson
haskell at alexjacobson.com
Wed Jun 23 15:38:42 EDT 2004
It would be really nice if you could pass an
error message down to every function that might
fail. e.g. using implicit parameters*:
myFunc 0 x = head x with ?failMsg="myfunc 0 caused the error"
Head would be defined as e.g.
head  = fail $ "empty list.\n" ++ ?failMsg
head (x:xs) = x
It would be even nicer if lineNumber was
automatically packed in the failMsg so the output
of myFunc  would be
Prelude.head: emptyList. [Line ???]
MyModule.myFunc: "myfunc 0 caused the error" [Line 50]
But, just being able to pass a msg would make
debugging LOADS easier (eliminating much of the
need for a debugger to supply a stack trace).
Since implicit parameters are part of the type
system, it would be even cooler to be able to
identify all the functions in your code that may
fail (i.e. that carry ?failMsg). You can then
target your debugging on those functions.
Does this make any sense?
* I've never actually used implicit parameters.
I just swiped the syntax I saw skimming:
S. Alexander Jacobson mailto:me at alexjacobson.com
On Wed, 23 Jun 2004, Fergus Henderson wrote:
> On 23-Jun-2004, Hal Daume III <hdaume at ISI.EDU> wrote:
> > On Wed, 23 Jun 2004, Fergus Henderson wrote:
> > > On 23-Jun-2004, MR K P SCHUPKE <k.schupke at imperial.ac.uk> wrote:
> > > > This may not be the right answer to the question (which is of
> > > > course lets write a debugger) - But I have never used a debugger,
> > > > and find them more or less the most unfriendly and useless things
> > >
> > > So how do you debug problems like "Prelude.head: empty list"
> > > in large programs?
> > Wasn't addressed to me, but here's what I do:
> > write the following function:
> > head_ x  = error ("head_: " ++ show x)
> > head_ _ l = head l
> > and then replace each occurance of "head" with "head_ 1" or "head_ 2"
> > etc., so I can know where it failed.
> Well, there are quite a lot of such occurrences in the code that I'm working
> bash$ find . -name \*.hs -o -name \*.lhs | xargs grep -w head | wc -l
> Replacing all of those occurrences by hand is going to be very very
> tedious and somewhat time-consuming. Doing it with a script would be
> better, but that's not a trivial task.
> Even once that is done, there's no guarantee it will actually help to
> find the problem. After all, the problem might well be arising from a
> call to "head" in one of ghc's standard libraries:
> bash$ find ~/ghc6-6.2/hslibs \*.hs -o -name \*.lhs | xargs grep -w head | wc -l
> So not only do I have to edit my own code, and the libraries written by
> my colleagues, I also need to edit the ghc library code, and figure out
> how to build and reinstall the ghc libraries. That could take a long time.
> After all that, hopefully I will finally know which function called
> "head" with an empty list. But even then there's still no guarantee
> that I've actually found the source of the problem; the real problem
> might be in that function's caller, or the caller's caller, etc. So I
> might have to go through the whole process again.
> > (it is rather sad that this is the best approach i could come up
> > with...basically tries to get around the [lack of/uselessness of/inability
> > to use with ghci] stack traces)
> Yes :-(
> Fergus J. Henderson | "I have always known that the pursuit
> Galois Connections, Inc. | of excellence is a lethal habit"
> Phone: +1 503 626 6616 | -- the last words of T. S. Garp.
> Haskell mailing list
> Haskell at haskell.org
More information about the Haskell