4 ms·
>most classes of bugs are caught at compile time This is false, can we stop pretending that hindley-milner solved the Halting Problem?
by alnayyir 15y ago
>most classes of bugs are caught at compile time
This is false, can we stop pretending that hindley-milner solved the Halting Problem?
- T_S_ 15y agoThink of it this way. More compile time errors = fewer run-time errors. You can still have bugs of course. Most my Haskell run-time bugs are because I defined a partial function. Many standard functions are partial too. I find that changing a working Haskell program to add new features is easier than other languages I have used. You pay a price (understanding your problem better) up front to get there, but the dev cycle is very fast after that.
- davidhollander 15y ago>More compile time errors = fewer run-time errors. But any possibility of 1 run time error means you'll still need to manually write a test asserting the correct runtime behavior anyway. So the typical argument is that typed languages don't actually save you any work, and might actually increase the likelihood of errors by discouraging unit testing. I'm not claiming this holds for Haskell, as my experience with the language is not great enough to pass any judgement yet.
- T_S_ 15y agoOk. Fewer run time errors = fewer tests. Also check out QuickCheck for automatically generating tests. It's very handy.
- Peaker 15y ago1 test is not enough to cover the functionality of various functions. In Haskell, types are enough to prove some properties about functions, so you don't need to write any test for the proven part. For example, you can write a RedBlack/AVL tree implementation in Haskell where the types prove that the tree is balanced. Haskell's type system is not strong enough to prove the order invariants are correct, though, so you'll still need to test that, but that's easier. In a language with a weaker type system, you'd end up with more test code (for balance tests) and less guarantees (tests give no assurance). Also, many bugs slip through tests that are meant to cover these classes of bugs. You don't get any guarantee from tests. Types give you nice guarantees. They're not as comprehensive as very-expensive tests, but they're pretty cheap. You get far more reliability-bang-for-the-buck from types, and thus the baseline from which you start testing is much higher.
- swannodette 15y agoIn fact one of the better books Simon Thompson's Haskell: The Craft of Functional Programming (better than Real World Haskell or Learn You A Haskell IMO) emphasizes the importance of testing.
- alnayyir 15y agoThis is a good example of what I really think we need: Testing, static analysis, and help from the type system.
- Peaker 15y agoYou don't need to solve the halting problem to solve most classes of bugs.
- alnayyir 15y agoMost? No. Some, a few? Yes. Also, stop trolling ##C with your Haskell stuff, nobody cares.
- Argorak 15y agoI think a better way to put this is that for example type errors are the first to bang really loud in any decent language. But Haskell does not help you with other, much more subtle and dangerous bugs. For example, a function not being tail-recursive despite you believing it to be.
- jeffdavis 15y ago"For example, a function not being tail-recursive despite you believing it to be." In haskell, I don't think tail recursion is nearly as important because of laziness. While one computation is adding more to the "stack", another is consuming. foldr, for instance, is not tail-recursive. It can return (partial) results given infinite input with constant memory. Of course, tail recursion is still important in the places that strictness is important. It's just not quite as fundamental in a language where laziness is the default. I think there are ways to tell if the TCO has been used, regardless. That's not a property of the type system, or even the language, but the implementation. If nothing else, the profiler should tell you quickly.