4 ms·
Monad has a specific set of mathematical rules, though, which have important properties which make them well-suited for some very specific tasks, including defi
by antonvs 6y ago
Monad has a specific set of mathematical rules, though, which have important properties which make them well-suited for some very specific tasks, including defining the semantics of programming languages.
I'm not aware of any "simple everyday concept", or anything in any mainstream programming language, that comes close to being equivalent to what monads are. You can find examples of specific monads being used (and misused) in many ordinary programs, because of their deep connection to programming language design, but they're never explicitly identified as such, partly because most languages can't conveniently make use of an abstraction like that.
Similarly, there's more to catamorphisms than what you describe. What you described is essentially what the generic mathematical concept of a catamorphism looks like in a specific context, but that's like saying that the term "vehicle" is just the simple everyday concept of a bicycle dressed up with a complicated neologism.
Something similar goes for bifunctor. `Either` is an example of a bifunctor, but it's also an example of a functor. Conflating the generic concept with specific instances will mislead you.
The point about this terminology, and the concepts it represents, is that it classifies these abstractions with precise rules, allowing the commonality across many different abstractions to be identified and exploited in well-defined, rigorous ways.
You don't find that in mainstream programming languages or the literature about them. The closest you'll come is things like object-oriented collection class hierarchies - Collection / List / Set / OrderedSet etc. That kind of classification is analogous to the sort of terms we're discussing, but is nowhere near as well-factored or mathematically rigorous.
> This eventually boils down to everything becoming for-comprehensions / do-notations.
What language are you thinking of? Sounds like Scala maybe. Unfortunately I think Scala was a mistake from the point of view of introducing functional programming to a wider audience. The object/functional mixture results in a kind of worst of both worlds that doesn't show off the benefits of either to best effect.
> usually typed FP code nowadays are full of compromises in the name of typing.
> But it's very easy to run into real world problems that require "hacks" or inelegant solutions, or forces the correct solution, which is very time consuming.
Perhaps you've had this experience from experimenting with functional languages, but it's not my experience from actually using languages like Haskell and OCaml in real projects for many years. I'm also very experienced with many mainstream languages - Java/Javascript/C/C++/Python etc. - and I find functional languages to be models of elegance by comparison. Statically debugging code by designing the types well ("make illegal states unrepresentable") is a huge timesaver when it comes to avoiding bugs and making significant changes to large codebases easier.
There's a lot of research on extending the power of type systems, which it seems like you may be thinking of, but for most ordinary purposes, you don't need to worry about that.
- pas 6y agoOf course, Haskell is right, the jargon is precise. That doesn't mean underlying concepts are not what everyday programmers use. The jargon has given proper names to the general concepts, it reified them, made them first-class citizens. I'm not saying they are not useful. (On the contrary, they are invaluable for high level discussions about certain aspects of programming, including control flow, data structures, and programming techniques.) Every async/await implementation is basically a monad with fancy syntax. > Conflating the generic concept with specific instances will mislead you. Yeah, agreed, no questions there. I'm just saying that the vast majority of programmers are nowhere near prudent enough to appreciate the strength of a correct/lawful system, plus they usually have other powerful concepts in their heads (after all there are many C programs that are sort of correct but not easily written with standard, total, and sound types, plus the required assumptions are not expressed in the source code). Also, another angle I think might help to convey what I'm trying to say is to look at how much jargon is needed to explain things like for-comprehensions execute the monad steps in sequence, but if you use mapN and an applicative then you can execute independent steps in paralell. Whereas it's just "race the futures" (or Promise.all, or whatever) in common programming parlance. > Perhaps you've had this experience from experimenting with functional languages [...] > What language are you thinking of? Sounds like Scala maybe. Yes, I don't know Haskell, I have a few years of Scala with some Scalaz experience. And maybe you're familiar with mypy and TypeScript, and it's obvious how problematic is to build the bridge between existing semantics and a correct/sound type system. (And of course, it's very much impossible, because you either have soundness or not, and so TS is unsound to be useful, and mypy is useless unless you rewrite many things.) > [...] and I find functional languages to be models of elegance by comparison I haven'got the hang of any pure functional language (yet?). I like to think it's not because of lack of trying. I see where concepts can be useful (eg. how TS and Rust would benefit from HKT, and how many people are waiting for a more expressive type system to create better abstractions, better libraries, better APIs), but to me all Haskell code looks like something like a dadaist poem with strange symbols sprinkled here and there. (Eg I'm looking at the sample app for miso https://github.com/dmjio/miso#sample-application https://github.com/dmjio/miso#sample-application and I have no idea what is what, no idea about shapes, what's <#, what's >>, why div_ and button_ have underscores after them, why div_ takes an empty list, what's {..}? And sure, most of these can be found, but still a lot harder than even the most damned FactoryFactoryBean in Java. And sure, I appreciate that lenses and the Transition interface helps with stuff, but that's simply a very small incremental ergonomic enhancment compared to what I wish. Similarly, when I look at servant's documentation I wonder how come a such powerful language, but to model 'GET /user/:userid' it can't - or doesn't - use /user/:userid, but "user" :> Capture "userid" Integer. The type is nice, and whatever :> is, I'm sure that's nice too, but I'm not finding the elegance that TSed has - https://github.com/TypedProject/tsed#create-your-first-controller https://github.com/TypedProject/tsed#create-your-first-contr... ) So, all in all, I'm just a lazy party-pooper when it comes to Haskell (or FP in general). And mostly just because the pain of debugging TypeScript and the myriad "any"-s everywhere still seems the lesser one than trying to grok the the cryptic symbols.