Although monads are not the only way to organize (effectful) computations, they are by all accounts receiving disproportionate attention.
Monads have a special, almost cult status in the minds of functional programmers. There is no doubt that monads clearly delineate effectful computations, in syntax and in types, and offer the reasoning principles (equational laws) about effectful programs. What many do not seem to realize is that these benefits are not unique to monads, or that not all effects are expressible with monads, or that the flexibility of the monadic encoding (‘overriding semicolon’) is limited.
Code generation and abstract interpretation, for example, do not fit the monadic framework.
Reddit, Stack Overflow, etc. discussion places are awash with misunderstandings and irrational exuberance towards monads.
That monadic programs cannot be statically analyzed by choosing a suitable abstract monad interpretation was the main motivation for applicative functors and arrows. Finally, we cannot pass on the commonly heard slogan that the monadic code is ‘pure’ (and, by implication, is ‘better’).
The fact that monadic code ‘desugars’ (is implementable in terms of) side-effect-free code is irrelevant. When we use monadic notation, we program within that notation – without considering what this notation desugars into. Thinking of the desugared code breaks the monadic abstraction. A sideeffect-free, applicative code is normally compiled to (that is, desugars into) C or machine code. If the desugaring argument has any force, it may be applied just as well to the applicative code, leading to the conclusion that it all boils down to the machine code and hence all programming is imperative.
Like Hughes, I object to the purity argument also methodologically. A particular programming style should be judged on its merits rather than on appeal to emotion. The merits (ease of writing, ease of implementing, code reuse among several implementations, extensibility) ideally should be evaluated by observation and experiment. Unfortunately, (properly done) empirical studies of programming styles are few and far between. From the personal experience, I have noticed that the mistakes I make when writing monadic code are exactly the mistakes I made when programming in C.
Actually, monadic mistakes tend to be worse, because monadic notation (compared to that of a typical imperative language) is ungainly and obscuring.
Человек то ли не понимает, что такое монады, то ли намеренно вводит публику в заблуждение. С теоретической точки зрения монады как раз и описывают машинный код (протаскивают состояние машины через цепочку инструкций). Их изначально в семантику для этого и ввели. Потому что с чисто функциональной точки зрения машинный код - это нонсенс, а денотационная семантика чисто функциональна. Вот эту проблему несоответствия и решили монадами/комонадами.
Абстракции не ломаются, просто одна монада трансформируется в другую.
На практике, с математической (логической) точки зрения, мы всегда работаем в монадах. Монады повсеместны там, где есть хотя бы переменные. Превращение колец в кольца многочленов - это тоже монады.
Самый ли это удобный способ выражения программ? Не знаю. Спорный вопрос. Вот в Lisp-ах мы всегда неявно живём в монаде списков, явно нигде монады не упоминаются, и это позволяет матрицы транспонировать через (apply map list M), и это круто.
Может, явный синтаксис для монад и не нужен, но знать про них и уметь с ними работать - навык полезный.