[Haskell-cafe] Re: Debugging partial functions by the rules

Claus Reinke claus.reinke at talk21.com
Wed Nov 15 18:19:09 EST 2006

>This isn't a trivial point. We know that error handling code is a major part of software cost--it 
>can even >dominate the cost of the "correct case" code (by a large factor). Erlang's "program for 
>the correct case" >strategy, coupled with good fault tolerance mechanisms, is one reason for its 
>commercial success--the cost of >including error handling code *everywhere* is avoided. But this 
>means accepting that code *may* very well >fail--the failure is just going to be handled somewhere 

I've been waiting for someone to put in a quick word for Erlang's approach;-)

if I recall correctly, the opposite to "programming for the correct case" was to
"program defensively" - try to predict and handle all errors where they occur,
and the arguments against that style were that:

1 it spreads error handling all over the place, obscuring the correct case,
    instead of factoring out the handling code into a coherent framework

2 it tries to handle errors where there is nothing to be done about them,
    leading to potentially dangerous "default values", or catch/rethrow,
    or even sweaping helpful diagnostics under the carpet.

As I've been trying to argue, the Haskell language report forces implementations
to handle functions with non-exhaustive left-hand sides defensively:

    - the left-hand sides are translated into a case on the right-hand side
    - the case is completed by a default branch calling error

since this behaviour is implicit, there is little that the programmer can do
about it, and unlike inlined partial matches (such as your getArgs example),
this forces the error to be raised where the offending context is no longer

it is perhaps a small thing, and mostly concerns everyone just once (because
once bitten, we try to "untrain" ourselves and our co-workers from using those
"easy" functions like head or tail, fromJust, etc.), but perhaps Haskell' should
fix this?

Instead of forcing implementations to let non-exhaustive functions accept
responsibility for arguments they are not equipped to handle, such arguments
should be rejected at the call site, with more useful error context.

>Haskell (or at least GHC) has good exception handling mechanisms too. We
>should be prepared to use them, and "let it fail" when things go wrong. The
>savings of doing so are too large to ignore.

indeed, though lazyness makes these things a little more cumbersome.

"let it fail" really means "don't worry about it here", but "have a safety net
separate from the main act" - lazyness might keep our failing trapeze artists
in mid flight until someone chooses to observe them, possible forcing them
to complete their crash after the safety net has been removed..


    API documentation withheld pending initial payment

More information about the Haskell-Cafe mailing list