15 ms·
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) to
by johan_larson 11y ago
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.
- devishard 11y agoThis 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.
- pron 11y agoIt's more complicated than that. Monads don't make a language more powerful, but they are an absolute necessity given Haskell's design, which is built around extensional/value semantics, which basically approximates a program/subroutine as the function it computes; this is a useful approximation as it lets us treat computations as if they were referentially transparent. That approximation has a cost, though, as computations are not quite functions (they are processes that compute functions), and while the approximation works well enough much of the time, some things require recapturing the more accurate definition of computations as continuations (i.e. a computation can block and then resume). If your language does not have continuations, only functions, monads achieve the same thing. If, OTOH, your language has continuations (as most non-pure languages do, although most don't have reified continuations, which are just as "programmable" as monads only more composable), monads don't really help. See http://blog.paralleluniverse.co/2015/08/07/scoped-continuations/ http://blog.paralleluniverse.co/2015/08/07/scoped-continuati...
- Peaker 11y agoIt's not really Monads making the language more powerful. It's the taking away of non-pure primitives and libraries -- and replacing those with type-labeled effects. That these effects are composed monadically is a minor detail and unfortunately the thing that's emphasized. Haskell gains power in its framework for restricting code. In Haskell, you can know so much about what code doesn't do -- and that's what makes Haskell special and powerful compared to other languages. You have to explicitly opt out of these restrictions - making the majority of code easier to reason about, simply because there is so much it cannot do.
- pron 11y ago> It's the taking away of non-pure primitives and libraries -- and replacing those with type-labeled effects. PFP and typing are quite orthogonal. You can have effect systems in non-PFP, continuation-based languages (i.e. languages that don't equate computations with functions). You can have non-pure, non-monad-based type-labeled effects. > Haskell gains power in its framework for restricting code. Sure, but Haskell does this within a very specific design, based on extensional functional semantics. There are other ways of restricting what code can or cannot do that don't have the same semantics. Personally, I think that various effect systems may hold promise and are certainly interesting enough to try, but the PFP abstraction has so far failed to yield results commensurate with its cost.
- Peaker 11y ago> PFP and typing are quite orthogonal They are orthogonal in 1 technical sense. But the benefits are reaped from the combination. > the PFP abstraction has so far failed to yield results commensurate with its cost. You say this based on what? Me and other Haskell users believe that the costs are very minimal and the benefits are quite huge.
- pron 11y ago> But the benefits are reaped from the combination. Well, I happen to think that some forms of rich typing are quite beneficial, but that value-semantics is a negative. I don't see Haskell having any tangible benefits whatsoever over, say, OCaml (other than ecosystem-related stuff), which has one (relatively rich typing) but not the other (PFP). > You say this based on what? Based on the fact that the few Haskell shops out there -- despite them being composed of avid enthusiasts and people who devote a lot of thought into the Haskell way of thinking, are not reporting even 2x productivity gains (although I don't know what huge means to you). I mean, some say they feel those gains, but when you look at iteration speed, time to market etc., you see negligible advantage if at all. As to the cost, I won't argue with you, but I encourage people who are interested in languages as well as in software engineering to try Haskell and judge for themselves.
- tome 11y ago> Haskell's design, which is built around extensional/value semantics, which basically approximates a program/subroutine as the function it computes; this is a useful approximation as it lets us treat computations as if they were referentially transparent. That approximation has a cost, though, as computations are not quite functions (they are processes that compute functions) This sounds "not even wrong" to me. Care to explain in more detail? > If, OTOH, your language has continuations ... monads don't really help. Haskell has continuations. Your move.
- pron 11y ago> Care to explain in more detail? What exactly is unclear? In Haskell, a subroutine or a subprogram is modeled as a mathematical function. Programs are not exactly functions[1] but continuations (i.e., they are a process which can be paused and resumed). There's absolutely nothing wrong with abstracting computations as functions (and there's much to be gained, which is why programmers are encouraged to write pure functions where possible, regardless of the language they're using), but sometimes you need to use their continuation-quality, and that's when you need monads. > Haskell has continuations. Your move. No, it doesn't. It models continuations as monads which is precisely my point. If Haskell subroutines were continuations, it wouldn't need monads, just as OCaml doesn't. [1]: If they were, then computations would be extensionally equivalent like functions, but they're not: an observer can tell if you're running bubble sort or merge sort, even though they're computing the same function (which is why type theory introduces has the concept of definitional equality). A lambda term or a Turing machine are not functions but continuations; you can start reducing a lambda term (or running a TM), block it (i.e. capture the reduced term/TM state), and then resume it.
- tinco 11y agoI 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.
- p4wnc6 11y agoMost 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 11y ago> Most people writing Haskell code for real problems should never write their own instances of Monad. Does using Free count? ;)
- whateveracct 11y agoUnderstanding 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.