
On Thu, Mar 26, 2009 at 5:23 PM, wren ng thornton
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?
Ultimately, it's not detectable statically, is it? Consider import Control.Applicative main = do f <- lines <$> readFile "foobar" print (head (head f)) You can't know whether or not head will crash until runtime. Alex