The problem I have with functional programming is debugging. Or more precisely, I would say it is a strength of imperative programming, especially the procedural kind. In functional/declarative style, you generally describe how things should be, not how things are made, and you let the language piece everything together to get the expected result in the end. It is all well and good (and even better) if you did everyt…
No other (mainstream) language comes close.
But what about situations where the code cannot be written in such a form (like shared memory concurrency)? I use transactions for that.
No other (mainstream) language comes close.
And that's without the low hanging fruit of no nulls, no implicit integer casts, etc.
It is absolutely true that debugging Haskell code is harder than debugging other languages. If you took away the bottom 90% of footguns, how could it not be?