top | item 11513883

Why does Haskell, in your opinion, suck?

196 points| kccqzy | 10 years ago |reddit.com

204 comments

order
[+] akavel|10 years ago|reply
Haven't seen it listed neither here nor there, so not sure if I'm the only one, but: for me, the first and currently blocking obstacle is of "graphical" syntax. I'm of the kind of people who hear the words they read as a voice in their head, so when every line is interspersed with multiple "random" <:> >>= <=< @>-,-'-- and whatnot other ascii-art I can't verbalise, I distictly feel my brain stumble, mumble, and grind to a halt and sad emptiness. And I don't even know how to google any one of them. Don't know how to solve this for myself. I've once found a list of suggested names for some common ones, but - I don't like having to learn all that by heart before I even start with the language; and also I feel pretty certain those are not all, and many libraries seem to like to invent their own new ones, so back to square one.

That's I believe the main reason I find SML more attractive: it seems to use operators to a much, much lesser extent, apparently preferring alphanumeric function names in the core, and in 3rdparty libraries too.

[+] darksaints|10 years ago|reply
Haskell has 3 major problems that are completely distinct in my opinion.

Biggest technical problem: lazy evaluation. Other people have said more than enough here.

Biggest cultural problem: technical oneupmanship and code golf. Haskellers can get so caught up in no-compromises stylistic competition that it makes it hard to get anything done. If you finally finish up something that accomplishes your goals, your teammate is gonna come in and rewrite everything you just wrote so he can feel happy with it too. And then lecture you about how lenses are wonderful and how you need to learn the principle of least power.

Biggest community problem: a small minority of extremely obnoxious and toxic assholes. They raid other communities and make fun of their languages and members. They rant against and mock everything deemed inferior. They treat people like they're idiots for not understanding basic but unfamiliar principles of the language. And nobody ever seems to shut them down, despite the fact that the majority are pretty welcoming.

[+] tome|10 years ago|reply
> They rant against and mock everything deemed inferior. They treat people like they're idiots for not understanding basic but unfamiliar principles of the language. And nobody ever seems to shut them down, despite the fact that the majority are pretty welcoming.

I'm happy to try to shut them down but I've pretty much never seen it (perhaps because I'm not in those other communities). If you do, please point me to it. Contact details here: http://web.jaguarpaw.co.uk/~tom/contact/

[+] js8|10 years ago|reply
> Biggest technical problem: lazy evaluation. Other people have said more than enough here.

I am actually wondering about that. It is considered essential by the classic paper "Why functional programming matters", for better program composition.

In particular, I wonder how are you supposed to pass around IO monad (or any other thing whose evaluation will give you side effects) as a value, if you have strict evaluation. I thought the whole point of Haskell was to lazily create a "recipe" as an IO monad, which will then be evaluated after it is returned from function main. In particular, I wonder how Idris deals with this problem, as I read it has strict evaluation.

[+] T-R|10 years ago|reply
Lazy IO's an issue, but Lazy Evaluation? It's not that different from writing SQL, and the places where it is, it's a lot more consistent, predictable, and tuneable. It's usually just bad defaults like Lazy IO, or String instead of Text that get you, but there's some consensus to move away from that.

There are definitely some toxic assholes, as in any community, and it's really shitty if they're going to, e.g., /r/java and harassing people. I feel pretty strongly that the opposite is a more common problem, though, particularly on HN: the anti-intellectualism against functional programmers, and Haskell users in particular, is rampant and gets pretty offensive. Example off the top of my head - https://news.ycombinator.com/item?id=10527745 - article simply explaining a math concept gets, as what was the top comment at the time, a condescending comment calling it all "mental masturbation". I've stopped reading HN so much because it's pretty clear that people trying to learn abstract algebra and apply it to code aren't welcome here.

[+] guard-of-terra|10 years ago|reply
In my opinion, Haskell community was very warm and helpful, and also able to admit shortcomings.

This was before Stack Overflow reshaped the landscape. On Freenode, ##java was a pretty hostile place (having to deal with people asking to do homework for them or being overall clueless) with attitude "if you see a problem with Java, the problem is you". The culture was so toxic that "forces of evil" ended up stealing the channel from under its original founder and banning him.

On #haskell, you would be immersed in polite chat revealing the development in all things FP, plus even pretty stupid questions were answered in such way that they enlightened both the asking person and bywatchers.

Also they had quite a few awesome bots that let anyone practically develop directly in IRC.

[+] YeGoblynQueenne|10 years ago|reply
>> Haskell sucks because both the standard library and the ecosystem lack guiding ideas. The former often feels like it is an amalgamation of PHD theses that have been abandoned soon after being complete.

That's a bit on the nose. [1]

[1] As in "ouch".

[+] davesque|10 years ago|reply
My main gripe is that the syntax is too sugary. I've often wondered to myself what a Haskell with syntax more in the spirit of Python would look like. I just wish I didn't always feel like I had to literally memorize what various custom operators meant with flashcards or something. Also, Haskell has relatively complex parsing and evaluation rules. The meaning of well-written code shouldn't be obscured by syntax.

And, along the lines of the syntax, the culture of style in Haskell. Single letter variables abound. Not just throwaway vars where the meaning is pretty clear from context. Entire libraries written with only single letter or acronymic variable names. Good luck understanding what a library author was trying to do by reading their code. I think this culture problem is largely being driven by the fact (which I mentioned) that Haskell's base syntax is already very opaque. I understand that the language takes some cues from the mathematical community (not surprising given its history). However, the language needs to ditch this to gain broader acceptance.

And, again, leading into my next point: the culture of the community in general is too academic. I'll make another comparison with Python. The Python community, among scripting languages, leans more toward the academic side but in a good way. They've found a nice balance. It's easy to get started and, if you want to learn more about the details, you can do so. With Haskell, you immediately get hung up on the details. Most of the details have to do with how Haskell fits into the framework of category theory. However, most programmers don't give a shit about provability. They just want to write software that is faster, safer, and more concise without being terse. I'm not convinced that it's impossible to have this in a functional language with the same goals as Haskell. Beginners should be able to get started quickly and without much confusion. If they're curious about the underlying principles, they should be able to gradually peel back the layers and learn more.

[+] amelius|10 years ago|reply
My biggest complaint would be about incomplete documentation of GHC. Given that Haskell is a pure functional language, it should be possible to easily use any part of the compiler, and include it in your own project. However, the documentation is rather incomplete, difficult to understand, and always behind the current state of the code. That said, the scientific literature on Haskell is the complete opposite, and contains beautiful work.

Also, I'm wondering why there are so few fully compliant implementations of the internet RFCs. Such specs seem an excellent opportunity to showcase the power of functional languages, yet the implementations keep lacking.

[+] lallysingh|10 years ago|reply
I haven't found a language where that isn't the case.
[+] POSIXprog|10 years ago|reply
Bryan Cantrill's take: https://youtu.be/0T2XFSALOaU?t=2021

My answer would be lazy evaluation by default. It's extremely unusual, and I've never seen a convincing enough justification for it, and it gives rise to performance bugs (space leaks) that can be fiendishly difficult to track down and fix and are disastrous in production. With the arrival of Idris, I think we can pretty conclusively say this was a mistake and that the Miranda branch of the PL family tree is likely to prove to be an evolutionary dead-end.

[+] bernalex|10 years ago|reply
Hallo. I see some of you are listing things here. It really would be very helpful to me if you could list them on Reddit as well, using the format of the thread, so that I only have one source to deal with.

I don't mean to instigate any Reddit vs. Hacker News rivalry, or whatever, but I just don't have time to go over several sources for my talk and PDF. So this is just a tip for if you want me to include your Haskell "complaint".

Glad to see the thread has sparked discussion here too!

[+] tlogan|10 years ago|reply
I had chance to debug one tool built using Haskell. I was amazed how Haskell solution for clean and easy to understand (it was a parsing library generating better optimized SQL queries).

The main problems are:

- it is hard to find examples/snippets of real-world solutions on net (majority of examples are like Hello world and these examples are not useful)

- lack of documentation about building real-world solutions

Maybe more work should be done in explaining how Haskell can be used to solve some real-world problems. Parsing seems like place where Haskell shines and more examples should be available.

So maybe just focus on "parsing with Haskell" and win that space.

[+] angerman|10 years ago|reply
Having these kinds of threads, I think, is very important for the community. On a related note, there has been quite some fallout from the haskell compilation times got worse thread, which resulted in the development of tooling around improving the situation.
[+] malisper|10 years ago|reply
My reason is that there are eight different folding functions:

foldl, foldr, foldl1, foldr1, foldl', foldr', foldl1', and foldr1'.

There are twelve if you count:

scanl, scanr, scanl1, scanr1.

Also, the implementation of monad transformers is disgusting. It requires O(n^2) code generation where n is the number of monads.

[+] Peaker|10 years ago|reply
Folds can be left-associative or right-associative. (l or r suffix).

Folds can be eager or lazy (prime suffix for eager).

Folds can work with at least 1 element to avoid the empty case ('1' suffix) (e.g: a function like `maximum`).

This gives 2^3 cartesian space of folds. Each and every one may be useful in some cases. For ordinary lists, though, foldr and foldl' cover virtually all uses (just use 'error' for the empty case when you need to).

Monad transformers don't require O(n^2) anything. You're talking about the 'mtl' package on top of the 'transformers' package. The 'transformers' package is useful on its own and doesn't have this problem.

The 'mtl' automatic lifter framework does require something in the order of O(n^2) instances (for n=6 or so). However, this is not really just 6 copies of the same code over and over. The threading of monadic state through different monads varies. For example: `Reader.local` is implemented very differently for `WriterT` and for `ContT`. So there really are in the order of O(n^2) different interactions to write code to account for.

[+] tome|10 years ago|reply
The non-primed versions simply shouldn't exist (everyone agrees) and in my opinion the 1 versions shouldn't exist either. This takes 8 down to 2, and they are genuinely two different functions so both need to exist.
[+] devishard|10 years ago|reply
I agree with the poster complaining about the wide variety of symbolic operators: readability becomes extremely important as programs grow large, and Haskell simply doesn't have it.

Lazy evaluation really doesn't pay off in my experience. Any major Haskell program turns out off for performance reasons. And when you don't, performance isn't the only problem: lazy programs often produce really inscrutable errors.

[+] yongjik|10 years ago|reply
I only dabbled in it a little for fun, but in my beginner's opinion:

Pros: The compiler eliminates a lot of potential bugs, so once my code compiles, I've saved hours that would have been spent debugging if I were using, say, C++.

However,

Cons: It takes more hours to figure out why my code is not compiling!

Basically, instead of debugging my code, now I have to "debug" GHC, trying to figure out what it is thinking and why it's rejecting my code.

Put another way, C++ allows me to try "quick and dirty" solutions first, and then later iterate and improve. Haskell requires me to be perfect at first try.

[+] johan_larson|10 years ago|reply
Haskell sucks because you can't really get anywhere before understanding monads well, and monads are (take your pick) a) too hard for most programmers, or b) too distant from the abstractions used in most programming languages.

Not that's you're done mastering Haskell when you've figured out monads, of course. There are plenty of harder abstractions running around. But monads are the orgo of Haskell, the place many earnest dreams go to die.

[+] tinco|10 years ago|reply
I don't feel at all that this is true. It is not necessary to understand monads to get good work done in Haskell for basically any purpose. Authoring monads is something usually left to library authors, and for basic users it's just a nifty interface that lets you do handy things in imperative style haskell ('do' syntax).

I don't want to be defensive in this thread, since obviously getting real about deficiencies in Haskell is a great way of making a path for positive change, but the spreading of the idea that monads are magical and hard is dangerous.

It's similar to how back in the day Java and PHP developers dismissed Ruby on Rails for being magical and hard to understand with weird syntax. The truth is that Ruby on Rails was very easy to use regardless of its rather complex innards, and once you get a good handle on Ruby, even the Rails innards weren't all that difficult to understand and extend.

The hard part of learning Haskell is getting to grips with functional style programming and understanding the power of its type system. Learning that is rewarding and has a low entry-barrier, it's even something I'd recommend to someone who has never programmed before. Don't worry about monads.

[+] devishard|10 years ago|reply
This would be a reasonable critique except that monads are really why Haskell ends up being so powerful and composable. Sure, they can be tough to wrap your head around, but without them Haskell wouldn't be particularly special or useful.
[+] p4wnc6|10 years ago|reply
Most people writing Haskell code for real problems should never write their own instances of Monad. When you see someone implementing tons of instances of Monad, it's a sign of over-engineering and Haskell masturbation. Very, very few people are good enough to judiciously understand when and where to write their own instances.

In the majority of cases you should merely be using instances of Monad which solve extremely common problems, like Maybe, List, State, Reader, Writer, and sometimes "functions of a common argument" `((->) r)`. The function one is perhaps the trickiest to understand.

For these examples of Monad, it's really not much work to learn how to apply them. Even just reading LYAH gets you pretty far. You could almost just pretend it is a DSL for composing units of work in each of the classic problems that motivate them (e.g. passing stateful computing, doing non-deterministic computation on a list, etc.).

But I do agree this becomes a huge problem when you join a team and they've architected skyscrapers of customized Monads to do routine stuff. That's a very poor way to build systems in Haskell unless you can guarantee every person on the team is a Haskell expert (hint: you can't).

Your comment strikes me more as a downside of the oneupsmanship of the Haskell community than a problem with Haskell itself.

[+] whateveracct|10 years ago|reply
Understanding monads sufficiently to work in monadic production code requires two things:

- Learning the type signatures of all the primitives of the Functor/Applicative/Monad hierarchy.

- Seeing some common monadic types in action. Basically understand how to interpret the "context" of M[A] and the semantics of bind. So Option[A] is a potentially missing A and bind short circuits. Writer[W, A] is an A with some accumulated W and bind accumulates the W. IO[A] is a description of an IO action that, when run, will yield an A and bind will create a new IO action that will use the result to produce a new IO action.

[+] Tinned_Tuna|10 years ago|reply
I actually really like the language, but there are several key points which stop me from using it in any production systems:

First and foremost, the build system. Oh god, the build system. Cabal is wonderful in some respects, but I have often found myself in a situation where the answer is "delete the ~/.cabal and ~/.ghc-pkg". This should not happen.

Laziness. You get concise programs, but then the memory performance is unknown until you read it and/or learn to read GHC's IR. You know, I'd really enjoy being able to know roughly how much memory I need to buy up for the systems I'm deploying.

Experimental or non-standard extensions. Just no. I'm not going to rely on non-standard or experimental "stuff" that tie me to a single compiler. This is made all the worse in that they're all hard-bound to various GHC versions and you're expected to use them in production (I'm looking at you, web frameworks). We have standards, stick to them.

It is for these reasons that I can't recommend Haskell to people as anything more than an interesting language to learn. Until the above is fixed (many of which are cultural) I will not use Haskell in production.

[+] olavk|10 years ago|reply
Haskell, like Perl, is optimized towards writing code rather than reading code. I would like a language which is to Haskell what Python is to Perl.
[+] bojo|10 years ago|reply
Very interesting and constructive thread. A lot of information about various Haskell warts, problems people have, and possible solutions to overcome some of them.
[+] tome|10 years ago|reply
Can I encourage everybody to classify their complaints according to the following scheme?

http://h2.jaguarpaw.co.uk/posts/complaining-about-languages/

I believe it would help everybody understand how we can improve people's experience around Haskell.

[+] pekk|10 years ago|reply
These are all interacting parts which make up a system. You can't separate the parts out so cleanly when they have so many interactions.
[+] johan_larson|10 years ago|reply
What's the difference between "infrastructure" and "tooling" in this context?
[+] Findeton|10 years ago|reply
I just prefer to use languages without a Garbage Collector.
[+] pmarreck|10 years ago|reply
I can tolerate it in Elixir/Erlang because GC is per-process-id (of which there could be dozens or hundreds in a typical Erlang/Elixir app) and not remotely a global world stopper.
[+] njharman|10 years ago|reply
Man! I'd never want to code in language that forces me to manage memory. A boring, solved problem the compiler/run time should handle for me.
[+] hkjgkjy|10 years ago|reply
Any experience doing functional programming without garbage collector?

I'm doing a lot of Clojure, and can't really see how it would be a pleasant experience without GC but curious to hear any interesting thoughts.

[+] pjmlp|10 years ago|reply
And spend time tracking down memory corruption?
[+] zzzcpan|10 years ago|reply
Most of these apply to other languages as well:

"Haskell sucks because compilation takes too long."

"Aye. And it takes too much memory too."

"My major gripe with haskell was that I could never tell the space/time complexity of the my code without serious analysis (that among other things involves second-guessing the compiler's ability to optimize). This makes writing good quality code harder than it needs to be."

"Debugging boils down to wolf-fences and print-statements most of the time"

"Profiling is needed for any stack traces, and is not enabled by default, so you end up spending hours rebuilding your sandbox just to get a stack trace of an error."

"Coming from a Scala background, the tooling seems terribly cumbersome and immature. I couldn't get it to work in IntelliJ."

"You need to turn on dozens of language extensions to do pretty much anything."

"I'm a developer on a pretty large Haskell codebase, and we're in a corner of 'can't add any libraries without them conflicting with each other." Which is OK, by itself, but leads to my biggest complaint of 'why aren't API changes reflected by major/minor versioning'."

"Haskell sucks because both the standard library and the ecosystem lack guiding ideas."

[+] YeGoblynQueenne|10 years ago|reply
For those who, like me, wondered what wolf-fencing is:

"Wolf fence" algorithm: Edward Gauss described this simple but very useful and now famous algorithm in a 1982 article for communications of the ACM as follows: "There's one wolf in Alaska; how do you find it? First build a fence down the middle of the state, wait for the wolf to howl, determine which side of the fence it is on. Repeat process on that side only, until you get to the point where you can see the wolf."[10] This is implemented e.g. in the Git version control system as the command git bisect, which uses the above algorithm to determine which commit introduced a particular bug.

[https://en.wikipedia.org/wiki/Debugging]

So now you know what that thing you always end up doing is called :)

[+] sisu|10 years ago|reply
"My major gripe with haskell was that I could never tell the space/time complexity of the my code without serious analysis (that among other things involves second-guessing the compiler's ability to optimize). This makes writing good quality code harder than it needs to be."

This problem is significantly worse in Haskell than in most other languages. Usually you lose at most a constant factor in performance if the compiler doesn't optimize as much as you expected, but the lazy evaluation can actually change the asymptotic memory complexity. I have been bitten by lazy evaluation several times by writing code that I expect to run in constant space and then finding it require linear amount of memory because of the evaluation order.

[+] vog|10 years ago|reply
> My major gripe with haskell was that I could never tell the space/time complexity of the my code without serious analysis

This is really a serious issue. The only other language where I ever had this issue was SQL. I had a project where we have lots of nested Views. We had to rephrase the SQL in sometimes very non-obvious ways, introducing intermediate Array results, CTEs, switching between sub SELECTs and JOINs -- all this just to convince the Query Planner to use a different Query Plan. That made a difference between < 1 second or a few minutes.

In the end, this is why I prefer languages OCaml or SML over Haskell. (Rust on the horizon)

Roughly speaking, in Haskell you can prove "just" correctness, while in OCaml you can prove correctness as well as performance.

[+] js8|10 years ago|reply
"My major gripe with haskell was that I could never tell the space/time complexity of the my code without serious analysis (that among other things involves second-guessing the compiler's ability to optimize). This makes writing good quality code harder than it needs to be."

It seems to me that there is some connection/analogy with garbage collection. Garbage collection also makes reasoning about space usage of programs difficult, since it happens in some future, yet unspecified, time. Yet GC is almost always regarded as good (although historically there was a lot of fight against it), yet lazy evaluation is regarded as bad by many. Maybe the issue really is "good enough compilers"?

[+] revelation|10 years ago|reply
Of course they do. The point here is exactly that all of those things apply to Haskell, simultaneously.
[+] hacker_9|10 years ago|reply
I think this shows that the tooling is just as important, if not more important, when choosing a language. Good debugging tools are a must simply because things always go wrong, and if I don't have an IDE that can highlight the line for me and allow to mouse hover over variable values, then the whole experience becomes a lesson in frustration.

Additionally if you expect me to 'write, build, run, repeat' just to test my code, then you better hope you have a fast compiler else I'm going to start associating using your language with the same amount of interest as watching paint dry.