I'm not arguing that Haskell can't improve in a lot of ways, but his complaints all seem to stem from attempting to program in Haskell using idioms that don't work well there. If you want to incrementally add to a data structure, use currying, or multiple constructors if that fits better. Don't use Maybes, and definitely don't subclass datatypes. He doesn't really seem to understand monads at all. If you want to log something, use a monad like Writer, not IO.
Agreed that, in some senses, I was trying to force a square peg into a round hole, but the comments on my blog suggest that others share my experience and they're mostly from planet.haskell.org. So I think something is missed if my experience is entirely chalked up to ignorance.
My post was written fairly quickly and got more attention than I expected. Looking at it again and looking at Turbinado's code, I can see how you could suggest that I don't understand monads. And I probably don't understand them to your level, but the code reflects the result of trying to compose together a number of libraries into a sensible system. Wrapping those libraries in composed monad transformers was vastly more complicated than just dropping down to the IO monad, so I stripped down...
w.r.t monads: they're lovely for constraining code behavior and for building DSLs, so other languages have added monad libraries. They haven't forced the entire language to live within monads...
w.r.t incremental data structures: I mentioned in my post that I wasn't happy with multiple data types. Multiple constructors sound even less productive. Currying is a solid suggestion.
The problem with Haskell is that it is way ahead of its time, in kind of the same way that lisp was ahead of its time.
lisp had high order functions and garbage collection, and now 30 years later all mainstream languages have these features.
Haskell has lazy evaluation, compiler enforced function purity and a type checker that doesn't get in your way. I predict that in 30 years all mainstream languages will have these features.
Well said, but I don't think it's a problem per se. Lisp was way ahead of its time, but it also hung around until everyone caught up with it.
Programmers tend to think about code at the level of the most powerful language they know. Show someone partial application who has never used it and they say "that's a neat trick I guess", but take partial application away from someone that is used to it, and they suddenly feel like something vital is missing.
So at the moment, Haskell's new ideas seem at best to be "neat tricks" and at worst "confusing" to most programmers, but, as with Lisp, those ideas and features will get added to other more mainstream languages a bit at a time. Haskell's contribution probably won't happen because a bunch of people go out and learn Haskell, but because it's ideas will slowly move the cluster of mainstream languages up the curve.
that's all true, but the type system in haskell is hard. it seems to me that means one of the following:
* i am old and stupid, and the next generation will find it easy (although i was about ten years younger when i first tried haskell, and it was simpler then...)
* technology will advance and better abstractions and/or interfaces will be found.
* programming really is that hard.
personally i hope for the second, suspect the first, and fear the third :o)
The reasons against Haskell in this article are quite shallow and he would benefit from more knowledge (Why putting functions in the IO Monad to log/write stuff ??).
Real reasons I have against Haskell are it's complexity: compare it to the average readability of Python. Often, to resolve a tough problem, you have to upgrade your "level", which can be considered good (you tend to resolve it in an intellectually satisfying way) or bad (others have to understand it...).
I'm really just beginning to learn Haskell while working professionally with Ruby. My gut instinct is that with Haskell you have to put in a lot of extra effort but you are repaid doubly in robustness. Obviously in real world scenarios there is a balance to be struck since a lot of code is just for throw-away purposes, or failure around edge cases does not affect the bottom line. However I suspect that the lack of traction Haskell gets in the commercial software world is more a result of human nature than actual economics of long-lived software projects.
The reason I'm bullish on Haskell is because I suspect it can be a significant competitive advantage in a lot of the type of data processing scenarios that start out simple in a startup, but can become slow/buggy/unmaintainable over time.
I don't disagree that the reasons are shallow, but it turns out that solving some problems in Haskell is just plain hard. It's precisely because the issues/reasons are basic that it's hard...
Also, I'm confused by your comment about the IO monad & logging... How would you log outside of the IO monad?
Would also be cool if you'd point me to your Haskell repo. I'd be curious to see how you solve these problems.
Can you clarify? I thought that keeping separate streams of side effects is not possible when one stream influences the other. The logging process depends on what actions happen in the IO sequence though not the other way around. Are you talking about keeping the normal IO actions in one monad, logging actions in another & then composing the two into an outer IO monad?
It depends on what you're logging. Pure code can keep its own log in Writer and then depose the whole thing to the IO logger later. Since there's no guarantee of the timing or synchronicity on non-IO code, this works well.
That's what I agree with: Haskell nearly requires programmers to read papers each time they want to solve a new problem [1]...
For the logging, I mean of course you can't be ultimately outside the IO Monad, but I don't like putting many things directly into it, if so I would prefer using the writer monad, or an additional argument, or something... I'm sorry though i don't have any public repo, I'm more of a lazy tinkerer...
Edit: [1] But I would like to add that there is also cultural bias of our comp-sci education, otherwise C++ can sometimes also be quite harsh...
Because it's conceptually different from what we learn, and semantically very rich. You have many 'aha!' moments, seeing that an abstraction corresponds to a really better way to solve a problem.
And because it's research oriented: maybe a simpler language with 80% of Haskell benefits will emerge out of it once those concepts have matured in Haskell.
And maybe mostly because people learning Haskell do it by curiosity, so they'd like to explore the best way to do it, not being under their boss/client 's pressure.
I'm starting to take this particular criticism as a major compliment to Scala. Scala makes it really easy to get stuff done and you're not forced to write functional solutions to imperative problems.
Also, I learned more from functional programming in Scala than I did when learning about Lisp. For one, Scala's default data structures are persistent and immutable, whereas the Lisp ones are mutable. Scala's library also operates better on abstract data types, whereas most functions in traditional Lisps operate on concrete data types, making Scala again more functional.
"Even Lisps are built on some primitive things, and those primitive data structures in traditional Lisps are mutable. I wanted the core data structures of Clojure to be immutable. In addition, I wanted the core algorithms to be based upon abstractions rather than concrete data structures as in traditional Lisps. These are things that can't be retrofitted in a compatible way."
I personally think it's sad that hardly anybody mentions OCaml or F# as alternatives to haskell. For a while I had the impression that OCaml had the potential to become really big but now it seems to have slipped people's minds. BTW it sounds odd to me that the author wasn't able to compile a hello world program and that he calls the error messages of the OCaml compiler incomprehensible. I could understand calling OCaml's type system complex (in comparison to the usual suspects).
And I still don't get the clojure hype. I probably would change my mind if there were a native clojure interpreter (like jruby for ruby) but the way it is you're tied to the jvm which precludes clojure from many use cases where a dynamically typed language would be preferable.