> It seems to me that every possible use of a partial function has
some
> (possibly imagined) program invariant that prevents it from
failing.
> Otherwise it is downright wrong. 'head',
'fromJust' and friends
> don't do anything to put that invariant in
the program text.
Well, not really. For example, I often write programs with command line
arguments, that contain code of the form
do ...
[a,b]
<- getArgs
...
Of course the pattern match is partial, but if it fails, then the
standard error message is good enough.
This applies to "throw away" code, of course, and if I decide to keep the
code then I sooner or later extend it to fix the partiality and give a more
sensible error message. But it's still an advantage to be ABLE to
write the more concise, but cruder version initially.
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 else.
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.
John