Haskell's main problem is that it is over-zealous, and built on axioms that make it a poor fit for real people writing real code. Everything else flows from that core issue. Functional purity and lazy evaluation are interesting, but when you can't toss a printf debug or log statement into a function without changing function signatures all the way up, it's not going to be popular.
Pragmatic, sloppy languages will always be more popular, because they are more forgiving.
To be fair, you can printf debug anywhere (Debug.Trace module). I'm the "print to debug" kind of guy, and I can debug in Haskell just like in Python using this.
I think the issue you have stems from the fact that people can't transfer the knowledge from C/C++/Python/wtv directly. One of the standard way to build programs in Haskell (mtl-style) allows you to perform IO actions almost anywhere, provided you're willing to play with monads. But this is so different from anything most people have ever seen that I understand why it can be frustrating.
Any idea when this was added? I am relatively certain that it was not possible in Haskell 98, and admittedly most of my Haskell experience is a decade old.
I have picked up three well-regarded Haskell books over the past decade trying to get back into the language, and don't recall any mention of this capability.
That's another issue, the dearth of anything like tutorials or books on how to do something practical with Haskell, rather than the whirlwind tour of language features. I keep being told that serious software is being built in Haskell, but the knowledge of how to get from university-grade code to production-grade code is an unmarked wilderness that everyone must apparently navigate on their own.
Looking back on historical GHC releases, the earliest one available on the web page is version 0.29, released in July 1995, and it already has the trace function. I would guess has been there for a long time.
The license on the Debug.Trace module says 2001... That's all I know.
I'm a big fan of the "Haskell Programming from First Principles" book. I read it on-and-off over the course of 2 years, and I think I'm an intermediate Haskell user at this point.
The most production-grade Haskell software I've ever played with would be Pandoc (document conversion) and the Yesod family of webdev libraries. Playing with Yesod is a bit scarier because it uses some Template Haskell magic. On the flip side, there's a great user guide (the "Yesod book").
> when you can't toss a printf debug or log statement into a function without changing function signatures all the way up
But you absolutely _can_ do this in Haskell.
Sure, it's considered very unsafe and shouldn't be used in production, but for printf debugging it's fine.
Admittedly, production-ready logging requires type signature modification, but if you subscribe to Haskell's idea that side-effects should be reflected in type signatures, then I don't see that as excessive.
Do you have any actual experience trying to solve something using Haskell, or are you just theorizing about how you imagine it would be "for real people writing real code"?
I've tried a few times, and bounced off quite hard. I'd rather go with something more pragmatic like Ocaml or Scala or F#. Particularly since all of those interop rather seamlessly with the vast array of existing code that is written for either the JVM or .NET, yet still give you considerably better type systems than the default C# or Java.
I tend to use Scala and Java for my day job. I completely understand you. Though I feel that a lot of what's good in Scala is better and simpler in Haskell, or was influenced by Haskell, so even if I don't use it for my day job, I feel it has made my job easier and better. Knowing Haskell has made me a better Scala programmer.
As an example, whenever I had trouble visualizing what some functions would do in Scala -- because they used to have horrible signatures, though it's getting better -- I would simply test the equivalent functions in GHCi to get a feel of what they would do, because Haskell functions tend to be simpler than Scala's ;)
Indeed! It’s an excellent low level imperative language. And amusingly enough bits low level libraries like vector and primitive that actually motivate a lot of the really fantastic type system innovations in ghc over time.
Pragmatic, sloppy languages will always be more popular, because they are more forgiving.