Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The bugs that static analysis tools tend to turn up are ones that Haskell catches out of the gate in general.

What Haskell brings to the table in terms of unique flavors of bug, I don't know. I would love to read articles about 1MLoC+ codebases in Haskell and how they play out.



Here are slides from a recent talk I gave on the 1MLoC+ Haskell code base we have at StanChart.

http://code.haskell.org/~dons/talks/padl-keynote-2012-01-24....

The guys on our team have between 4 and 25 years (yes, not a typo) experience with Haskell.

P.S. We are hiring in London, Singapore and Tianjin.

---

A couple of days ago was CUFP, by the way, which includes a series of talks from different business users. http://cufp.org/videos/keyword/2269


At Citrix we only have a couple dozen thousand lines of Haskell. But it's also a real world use.


If you're hiring in London, I'd be keen to find out more - any chance you could drop me an e-mail and point me in the right direction?

Thanks.



Tianjin? I only know of one guy in my entire lab in Beijing who even knows Haskell.


Part of what I mean is that some of what Coverity and friends cover aren't just bugs bugs, but things that are bad style and contribute to bugs in the future. For instance, you can put too many things in IO when you should be separating the IO code from the pure code. This can be perfectly correct at a given moment inasmuch as the program works correctly, but it certainly might encourage bugs in the future as the code gets modified. It would be interesting to see how much of this could be automatically detected.

As another for instance, partial functions can already be caught by some static analysis tools and we tend to think they are at least bad style (I would rate them as a serious code smell; every time I thought I wanted one, it was trying to tell me I had a fundamental design flaw), but they are certainly syntactically valid Haskell.


GHC will warn about partial functions/inexhaustive patterns if you compile with -Wall (or even just -fwarn-incomplete-patterns, but -Wall is recommended). I've often wondered if it would be feasible to eliminate the partial functions from the Prelude and turn partiality into an outright error (not that this would ever happen, as it would break a lot of code).

Regarding other code smells that the compiler can't catch: one thing I have come to really appreciate about the design of Haskell is that in the vast majority of cases, the path of least resistance is also the path of greatest clarity, correctness, etc. I mean, sure, you can write your entire program in IO, but it would be supremely irritating to do so. It's just simpler and easier to do it the "right" way, via composition of small, independent, pure functions.

When using other languages (for me, this usually means Java, Python, or JavaScript), I feel like I am constantly having to remind myself not to be lazy and to do things the way that I know to be right. Don't catch an overly broad class of exceptions. Don't rely on shared mutable state when an extra function argument will suffice. Avoid using null pointers to represent failure. Be sure not to use type-coercive comparison operators. And so on. These languages give you so many ropes with which to hang yourself, and even the standard libraries make idiomatic usage of them. Programming defensively feels like working completely against the grain.

Haskell, with its strong immutability and airtight type system, has shown me that it is possible for a language to guide programmers safely through the minefield without placing a severe additional burden of vigilance on their shoulders. It would be interesting to see a more conventional, imperative style language that followed similar principles. Or perhaps the "everything is in the IO monad all the time" nature of imperative code is just fundamentally at odds with code correctness, and we'll always have to fight against it.


I have a 25 kloc Haskell program, and by around 10 kloc I was sure I did't want to need to track down another backtrace-less crash with "head: empty list".

So, I wrote this module: http://source.git-annex.branchable.com/?p=source.git;a=blob;...

It's imported into every module in my program via a common include which also pulls in other support stuff. Now if I slip up and use head, I get a compile time error as there are two conflicting heads. If I really want to (after all, sometimes you have an invariant) I can use Prelude.head, and I can `git grep Prelude\.` to find all the partial code in my program (currently about 15 occurrences). Or I can read the fine comments in my module for a hint to a non-partial version to use.

There are other approaches, but I've found this to be a fine compromise.


> Or perhaps the "everything is in the IO monad all the time" nature of imperative code is just fundamentally at odds with code correctness, and we'll always have to fight against it.

In some languages, like D, you can fight against that, by declaring functions to be pure. That's a bit like having everything in IO by default, but marking the exceptions.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: