[Haskell-cafe] Use unsafePerformIO to catch Exception?
wren ng thornton
wren at freegeek.org
Thu Mar 26 20:23:04 EDT 2009
Jules Bean wrote:
> wren ng thornton wrote:
> > I have long been disappointed by a number of `error`s which shouldn't
> > be. For example, the fact that `head` and `div` are not total strikes
> > me as a (solvable) weakness of type checking, rather than things that
> > should occur as programmer errors/exceptions at runtime. The use of
> > `error` in these cases muddies the waters and leads to a laissez-faire
> > attitude about when it's acceptable to throw one's hands up in despair
> > and use `error` rather than writing a better function.
>
> head uses "error" in precisely the correct, intended fashion.
>
> head has a precondition (only call on non-empty lists)
And that is *exactly* my complaint: the precondition is not verified by
the compiler. Therefore it does not exist in the semantic system, which
is why the error screws up semantic analysis.
The type of head should not be [a] -> a + Error, it should be (a:[a]) ->
a. With the latter type the compiler can ensure the precondition will be
proved before calling head, thus eliminating erroneous calls.
It's a static error, detectable statically, and yet it's deferred to the
runtime. I'd much rather the compiler catch my errors than needing to
create an extensive debugging suite and running it after compilation. Is
this not the promise of purity?
> There are programming styles which avoid using 'head'. You are free to
> use those if you don't like it. I myself am content to use 'head' on
> lists which I know are guaranteed to be non-empty.
Avoiding head is not a tenable solution. The syntax for case matching is
insufficiently first-class, so avoiding the function often leads to
contortions, illegible code, or reinventing the problem. Moreover, this
isn't an isolated case; fromJust is another canonical example, as is any
other partial algebra-homomorphism. Many mathematical functions like div
are also subject to trivially-verified invariants on their arguments.
Functions like uncons and viewL are nicer (because they're safe), but
they can have overhead because they're unnecessarily complete (e.g. the
Maybe wrapper can be avoided if we know a-priori that Just will be the
constructor used).
--
Live well,
~wren
More information about the Haskell-Cafe
mailing list