So, given this, what I'm looking for are the downsides or problems that come along with Haskell. The web has a tremendous amount of information about why Haskell is a Good Thing, but I haven't found many topics about its ugly side (apart from gripes about its syntax which I don't care about at all).

An example of what I'm looking for could be like Python's GIL. Something that didn't rear its head until I really started looking at using concurrency in a CPython environment.

4 Answers
4

Due to the language's nature and its firm roots in the academic world, the community is very math-minded; if you're a pragmatic person, this can be overwhelming at times, and if you don't speak the jargon, you'll have a harder time than with many other languages.

While there is an incredible wealth of libraries, documentation is often terse.

Gentle entry-level tutorials are few and hard to find, so the initial learning curve is pretty steep.

A few language features are unnecessarily clumsy; a prominent example is how record syntax does not introduce a naming scope, so there is no way to have the same record field name in two different types within the same module namespace.

Haskell defaults to lazy evaluation, and while this is often a great thing, it can bite you in nasty ways sometimes. Using lazy evaluation naively in non-trivial situations can lead to unnecessary performance bottlenecks, and understanding what's going on under the hood isn't exactly straightforward.

Lazy evaluation (especially combined with purity and an aggressively optimizing compiler) also means you can't easily reason about execution order; in fact, you don't even know whether a certain piece of code actually gets evaluated in a given situation. Consequently, debugging Haskell code requires a different mindset, if only because stepping through your code is less useful and less meaningful.

Because of Haskell's purity, you can't use side effects to do things like I/O; you have to use a monad and 'abuse' lazy evaluation to achieve interactivity, and you have to drag the monadic context around anywhere you might want to do I/O. (This is actually a good feature in many ways, but it makes pragmatic coding impossible at times.)

@TikhonJelvis: Those are indeed the only two candidates I found worth using; "Learn You A Haskell" confused me more than anything, "Real World Haskell" worked for me but assumes a bit of a programming background. There's also "Gentle Introduction to Haskell", but it's all but gentle, especially if you lack a background in Math.
–
tdammersJan 26 '12 at 11:38

I use "Gentle Introduction to Haskell" and "Real World Haskell". The combination of the two gave me a lot of useful information. I am at a level where I am ready for a non-trivial project but unfortunately I do not have much time for it.
–
GiorgioJan 27 '12 at 15:54

5

"if you're a pragmatic person...": sometimes using a math-oriented language can be a very pragmatic decision if it avoids you a lot of bug-fixing later. Of course, you should always find a balance between how much time you save by using a tool, and how much extra time you need to learn how to use it.
–
GiorgioSep 21 '13 at 7:00

Most of Haskell's downsides (as well as most of Haskell's upside) come from its two defining characteristics: It's lazy and purely functional.

Being lazy makes it harder to reason about performance. Especially for people not used to laziness, but even for experienced Haskellers it can be hard to see how laziness will affect performance in certain cases.

Laziness also means that it's harder to create accurate benchmarks without using libraries like Criterion.

Being purely functional means that whenever you need to use mutable data structures (in cases where it's not possible to achieve the desired performance without them - though thanks to GHC's optimizer that doesn't happen as often as you might think), you'll be stuck in the IO (or ST) monad, which makes the code more cumbersome.

Since you mentioned speed as one of your goals, I should point out that there are often huge differences in performance between hand-optimized Haskell code and Haskell code that was written without giving much thought to performance (more so than in other languages). And hand-optimized Haskell code is often quite ugly (though I suppose that is also true in most other languages).

Purely functional is actually a selling feature, not a downside. A language being "lazy" makes no sense, lazy vs strict is a matter of types, and both lazy and strict types have their uses. (So Haskell is just as crippled by not having strict types as most languages are crippled by not having lazy types.) Haskell's main downsides are its crappy module system (modules are not first-class) and the fact type classes actually break modularity (the "one instance per type" rule forces the compiler to keep a global list of type class instances).
–
Eduardo LeónJun 23 '13 at 13:38

9

"And hand-optimized Haskell code is often quite ugly (though I suppose that is also true in most other languages)." This. When people want to show the elegance of Haskell, they publish short and sweet code, which unfortunately would give you quite bad performance if run on a production-like amount of data. When people want to show that "Haskell is as fast as C++", they publish convoluted and hard to read code, which is still slower than a much more readable version in C.
–
quant_devSep 20 '13 at 17:01

I am not a Haskell expert: I have learnt the basics but unfortunately I haven't
had the chance to do some serious project in Haskell (I would like though, because I like this language a lot).

However, from what I know and from a discussion with somebody who's been working
in a field quite close to functional programming, Haskell might not be the best
solution when you want to implement graphs algorithms, where you need e.g.
to walk through the graph and perform many local changes on the graph structure.

Since a graph does not have a recursive structure in general, my feeling is
that the best approach is to build one copy of the graph using structures
and pointers between them (as you can do e.g. in C++) and manipulate that
copy by changing pointers, creating or destroying nodes, and so on.

I wonder how such data structures and operations can be handled properly
in Haskell, since to my knowledge in Haskell it is not possible to use the above representation / approach. Some problems with graph algorithms in Haskell are briefly discussed in this article

EDIT

I recently spoke with an expert of functional programming and he confirmed that implementing certain graph algorithm efficiently can be quite tricky in Haskell: moving around pointers like you do in C or C++ can be much faster.

Purely functional graph algorithms are an interesting topic. The idiomatic solution is to emulate the imperative representation by replacing pointers with purely functional dictionaries, e.g. mapping a given vertex to the set of vertices that it has edges to. However, unless a weak dictionary is used this will leak memory because unreachable subgraphs cannot be collected and there is no known purely functional weak dictionary. At the end of the day, a state-of-the-art purely functional solution is both far more complicated and far less efficient!
–
Jon HarropFeb 26 '12 at 16:15

On the other hand, graph algorithms can be notoriously difficult to debug and persistent data structure can alleviate this problem...
–
Jon HarropFeb 26 '12 at 16:20

I was wondering if it would be possible to develop a graph data type (following the idea of ByteString: efficient internal representation plus conversion / access functions). Using monads it should be possible to make such graphs mutable. Of course this would address the issue of of representing graphs but not that of implementing graph algorithms.
–
GiorgioFeb 26 '12 at 17:49

The down side to Haskell is that its different. It's a bigger step away from languages that are more commonly taught or talked about, so there will be a larger learning curve. It's also less popular of a language which may limit availability of help if you get stuck. These really aren't major downsides though.

The one thing that is a potential downside is that it's a functional language, so it is less useful for certain problem domains, but this is true for object oriented languages as well. Generally languages don't have true negatives beyond learning curves, at least for the relatively popular languages. As long as a language is Turing complete it is theoretically capable of anything.

What are those "problem domains" for which Haskell is allegedly less useful?
–
Andres F.Jan 26 '12 at 1:05

1

While it's true the community is smaller, it is actually disproportionately active. I think the #haskell channel on freenode is only behind #python in popularity within the language channels, and answering questions about Haskell on SO is surprisingly competitive :)
–
Tikhon JelvisJan 26 '12 at 3:22

@AndresF. - I wouldn't go so far as to say "less useful," but here are some areas where Haskell is definitely still showing its infancy: 1) heavy DP -- I coded up a simple knapsack algorithm, and was literally shocked at how slow it was. That was using boxed arrays, so I expected some overhead, but it was a lot worse than I anticipated. 2) large non-trivial games -- AFRP is in its infancy, so there are no particularly good frameworks, and performance is still too difficult to predict. It will be a long time before we see the Haskell version of Doom. (frag doesn't count -- it has no AI.)
–
rtpersonJan 31 '12 at 15:15