- Competitors with Coverity are CodeSonar[1] and Klocwork[2]. I've not seen Klocwork output, but CodeSonar and Coverity are in the same area of quality, with differing strengths. I can not recommend static analysis highly enough if you have a C/C++/Java/C# database. It's very expensive (well into five figures according to Carmack), but how expensive is a bug? What if you have your entire codebase checked daily for bugs? Consider the effect on your quality culture. :-)
- The fact that you are paying "well into five figures" for a tool that essentially covers up design deficiencies in your language should start sounding alarm bells in your head. The proposition more or less goes, "To have reliable C++ code in certain areas, you need a static analyzer; to gain that same advantage in Haskell costs you nothing more than GHC". Of course Haskell doesn't have certain C/C++ capabilities; but it's worth meditating on for your next application, particularly if bugs are more important than performance. N.b- I don't know the ML family enough to say one way or the other in this regard. :-)
The fact that you are paying "well into five figures" says more about the sales process than anything else.
Any time you have dedicated sales staff selling stuff to organizations with a sales process that needs to get buy-in from executives, your prices have to go way up to cover that cost. (Doubly so because the sales process is expensive for you, and your price point lowers your success rate.) Unfortunately many organizations have a rule that every purchase over $X has to be approved by management. Thus there are 3 price points that you can find proprietary software sold at:
1. Small enough that a developer can charge it to a corporate credit card.
2. Relatively modest recurring payments, individually small enough to pass on a corporate credit card.
"To have reliable C++ code in certain areas, you need a static analyzer; to gain that same advantage in Haskell costs you nothing more than GHC"
It is certainly true that many of the static errors that Coverity and friends can find aren't possible in Haskell because it won't compile, but I'd like to see a lot more public experience with Haskell and larger projects to see what the result would be for other problems. A lot of what we now know about how C++ should be written is the result of decades of hard experience, and who knows what we might find in Haskell with as much experience.
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.
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".
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.
On the Java end (all though these tools also do C/C++ and other languages maybe even .NET but their speciality from my understanding is Java) is Fortify [now owned by HP] and IBM AppScan Source [previous Ounce from Ounce Labs].
Both produce high quality output in their domain. Fortify is widely use in the AppSec world.
Accuracy. Detail. They have better analysis engines, which do more complex types of program analysis. The static program analysis field is incredibly deep it takes a lot of engineering to make a world class analysis engine. Just like it takes a lot of effort to make a world class optimising complier. (eg. the Intel C Compiler still out performs GCC despite monumental effort on GCC's side. It takes a long time to build this stuff)
They also have better rules sets from what I understand than the open source tools.
While the Intel compiler may be better in some/many cases, it is not universal. In my experience (a couple of years ago, C++ code, high-performance requirements), the Intel compiler was quite a bit worse than GCC for code with a lot of branches and abstraction layers.
The Microsoft compiler was way better than both. Around 10% faster run-time IIRC.
And if you don't want to jump into Haskell's strangeness right away, there's always OCaml. It's fast enough for finance, so it should be fast enough for you.
(I prefer Haskell, it's much more beautiful. But that's more of a religious issue. OCaml is still way better than, say, C++.)
For having extensively programmed using C++ and OCaml, I could not agree more.
The issues that most people focus on however are : portability to the platforms they're concerned about, performances on these platforms, richness of the ecosystem.
Game programmers cannot consider Haskell or OCaml as real alternatives to C++ for these reasons. Yet.
That said, people learning to use these languages become better programmers overall. They get a better sense of how to structure, validate their data, and avoid a lot of pitfalls. Have look at the answer made by a representative of one of the products mentioned by J.Carmack - she goes through some of the reflexes she acquired while using her product, and there's definitely an overlap with the way people code using Haskell or ML. It's not an accident that C++ is moving toward incorporating features from functional languages.
Just for these reasons alone people should learn to code with languages like that.
Yes. Though, as with lots of projects, the core that has to be written in a C or C++ can be relatively small. Haskell's FFI is quite powerful, and it should be possible to use it in a way similar to how people embed Lua.
I wonder if there are languages who have the reliability of Haskell's type system, but are suitable for C/C++ stuff (that probably means, at the very least, they're strictly evaluated). ATS came up as a possible candidate, does anyone have real experience with it?
BTW, I once considered this (this being a language with Haskell's strengths, suitable for systems programming) a possible idea for a thesis, but at least for now it's put on hold. If anyone has any comments, I'd really love to hear them.
I've used ATS a fair bit in real programs. The back end of my bitcoin mining pool is written in ATS and handles a reasonable load. I've also used ATS in other projects and am happy to answer questions you might have. Contact details at the bottom of the website linked in my profile.
Do you know about OCaml? It shares lots of Haskell's type system, but it's strict.
There's also lots of work being put into Haskell right now, to make it more suitable as a low level language---some by direct work on Haskell, some by making it easy to embed DSLs that compile to carefully restricted low level code.
Sounds cool, can you provide some pointers to that work? 10x
BTW, I wonder if they allow the programmer to better control when and how much memory is allocated, that seems to me like the biggest obstacle for using Haskell for low-level stuff.
I can't say I know enough about it to say either way, in the article Carmack says:
Technically, the Microsoft tool only performs local analysis, so it should be inferior to Coverity’s global analysis, but enabling it poured out mountains of errors, far more than Coverity reported. True, there were lots of false positives, but there was also a lot of scary, scary stuff.
According to a very insightful, but perhaps now slightly old article (http://cacm.acm.org/magazines/2010/2/69354-a-few-billion-lin...) Coverity tries--for political reasons--very hard to keep false positives down, very much at the expense of false negatives.
I'm pretty sure Coverity has multiple "tiers" of analysis, with the initial tier being the subset they're most certain of. Once you fix most of the obvious, almost-no-false-positive type stuff, then they're ready to show you the next tier.
- Competitors with Coverity are CodeSonar[1] and Klocwork[2]. I've not seen Klocwork output, but CodeSonar and Coverity are in the same area of quality, with differing strengths. I can not recommend static analysis highly enough if you have a C/C++/Java/C# database. It's very expensive (well into five figures according to Carmack), but how expensive is a bug? What if you have your entire codebase checked daily for bugs? Consider the effect on your quality culture. :-)
- The fact that you are paying "well into five figures" for a tool that essentially covers up design deficiencies in your language should start sounding alarm bells in your head. The proposition more or less goes, "To have reliable C++ code in certain areas, you need a static analyzer; to gain that same advantage in Haskell costs you nothing more than GHC". Of course Haskell doesn't have certain C/C++ capabilities; but it's worth meditating on for your next application, particularly if bugs are more important than performance. N.b- I don't know the ML family enough to say one way or the other in this regard. :-)
[1] http://www.grammatech.com
[2] http://www.klocwork.com