I know my original comment is sort of bratty, and I was confusing monoids with monads, which... is a different functional thing that people apparently use?
It feels like mon(a/oi)ds are a concept that gets regularly explained on various blog posts. I read/skim the blog post and don't understand what they are or how they're useful (which is clearly on me). And then I read the comments, and they're split between some folks saying "I still don't get it" and others saying, "Yeah, these are common, easier than you think, and incredibly useful in Haskell/Scala/Clojure/F#/whatever". And then the world moves on, and the cycle repeats the next month. It doesn't seem like the number of people who say "I still don't get it" ever goes down. Which is why the comment about how they're not happening.
I absolutely promise you that you have used a monoid. Addition is a monoid!
The thing you might not have done is recognized that a subset of the rules of addition end up showing up all over the place and therefore you can translate some of your intuition about addition to these other places.
As a simple example, you might notice that the `length` function converts strings to numbers in such a way that
length(concat(X, Y)) = length(X) + length(Y)
in other words, length converts the "string monoid" to the "addition monoid" in a very neat way. You can sort of see that it converts "concat" to "+".
This isn't even some kind of mumbo-jumbo "intuition translation". It's a literal dyed in the wool functional translation.
So is there reason to believe that monoids won't be going away anytime soon? I think so—they've already been around and in HEAVY use since the dawn of abstract algebra in the, I dunno, perhaps the 30s?
Yes, monoids and monads are different concepts. Monoids are the easier one
It's not the names that matter, or even necessarily the properties, but the general shape of monads and monoids is one we find ourselves using all over in functional programming. A very large percentage of the Scala standard library is classes with monadic properties, even though Scala does not have a monad type built in.
So it's not that people really need to understand monads to do functionall programming: I think that understanding them is unimportant. The difficulty of the concept is proven by what you mention: Tons and tons of blogposts trying to, and failing to, explain monads.
As far as the utility of monads, just look at actual monads that are very useful everwhere. For instance Option avoids large amounts of null checks, making code easier to write and read. And why is this? Because it's a monad. I can transform any type A into an Option[A], and an Option[A] into an Option[B], by just having a function that transforms A into B, unaware that option exists.
Understanding category theory makes it easier to write good, useful mechanisms that take functions as parameters. But we can use a monad without understanding that it's a monad, and that's fine for most people. It never has to be a thing.
Yes. I have two explicit monoids in the production codebase I'm working on professionally right now. The simple case is one where I use foldMap to put together some values in a list. In isolation it's only saving a few lines compared to an explicit summing loop - but if you can "replace a few lines with a single method call" in a lot of places in your code, you end up with much more readable/maintainable code.
The other is more complex but also shows the power a bit more: a report that wants to accumulate some statistics separately (something like "12 successful, 45 error A, 2 error B"). So I have a type representing that:
case class Stats(successful: Int, errorA: Int, errorB: Int)
So with very little code, my report steps all include a "stats for this step", and they automatically accumulate into an overall stats object. Of course this is nothing I couldn't have written myself, but the library methods already exist and help.
More importantly though, I have another report that uses the same infrastructure, but makes async HTTP calls. So that report uses Future. But I can share common code between the two reports easily, because my abstract superclass is just `Report[F[_]: Monad]`.
I think they are happening, slowly but surely. Five years ago I wouldn't have dared suggest explicitly using Monad in production code. Two years ago we used one single Monad across our whole application, and even that was controversial. Now our codebase has more than I care to count.
The thing is that the idea "using a monoid" will not make much sense unless you're using a language which makes such things explicit. Type classes let you use monoids in the most obvious way; that is, by creating a type class called Monoid, writing instances of the class for various types, and writing functions that are generic over any monoid. In this sense you're obviously "using monoids" because you're writing Monoid somewhere.
In most other languages, the idea of a monoid will appear in the form of an abstraction of operations such as addition. For example in python, the `int` and `str` types both have a sense of addition via the `+` operator, such that 'a' + 'b' == 'ab' and 1 + 2 == 3, etc. Now this is a step in the right direction, but for example in python the same doesn't hold for sets: you might think that `{1, 2} + {2, 3} == {1, 2, 3}`, but you'll get a type error with that. The operator is `&`. Furthermore, for some bizarre reason, even though you can add two strings and two numbers, you can `sum` a list of numbers, but you'll get a type error if you try to use the `sum` function on a list of strings.
The problem is that there's no real concept of what `+` really is, in the abstract sense. Is it addition? Then why can't I sum a list of strings? Is it joining two things? Then why can't I add two sets? This kind of arbitrariness is what monoids (and other type classes) help address. Any type which has an associative operation and a neutral element is a monoid, full stop. This allows us to write, for example, a sum function which can take any list of elements of some monoid. In Haskell this is called mconcat:
mconcat :: Monoid m => [m] -> m
mconcat [] = mzero
mconcat (object:objects) = object <> mconcat objects
Now we will have `mconcat ["hello", "world] == "helloworld"`, and `mconcat [1, 2] == 3`, just like we expect. We also have `mconcat [{1, 2}, {2, 3}] == {1, 2, 3}` as well! (Pretending there is such a syntax for set literals :)). Because integers, strings and sets are all monoids.*
Worth noting is that in haskell the `+` operator comes from a separate type class, that of numbers. In that sense Haskell draws a distinction between things that can be added, in a numerical sense, and those that can be joined in a more abstract sense (for that the operator is `<>`).
So in summary, the concept of a Monoid is just one example of the power of type classes to provide convenient abstraction, while simultaneously giving a clear sense of the behavior the abstraction is meant to provide. You've probably used monoids before, and I'd wager there were times when you wished you had monoids (or even implemented them yourself), even though you didn't know it. ;)
Regarding the rest of your post: it's an unfortunate fact that monoids and other functional programming concepts often go in one ear and out the other to those who aren't avid proponents of them already. This is probably in part due to the hifalutin-sounding names, absence of familiar syntax and paradigms, and sometimes writings which assume too much of the reader (or too little). However, if you look at the evolution of people do programming, it's pretty clear that the world is embracing more and more concepts from the functional world every day. Despite the number of people "not getting it", I have to think the situation wasn't that much different a good 10+ years or so when first-class functions were a fancy new concept.
* Oddly enough, Ints aren't monoids natively in Haskell, because you can define them as monoids in two ways (with 0 and addition, and with 1 and multiplication). But for the purpose of demonstration, I glossed over this...
I know my original comment is sort of bratty, and I was confusing monoids with monads, which... is a different functional thing that people apparently use?
It feels like mon(a/oi)ds are a concept that gets regularly explained on various blog posts. I read/skim the blog post and don't understand what they are or how they're useful (which is clearly on me). And then I read the comments, and they're split between some folks saying "I still don't get it" and others saying, "Yeah, these are common, easier than you think, and incredibly useful in Haskell/Scala/Clojure/F#/whatever". And then the world moves on, and the cycle repeats the next month. It doesn't seem like the number of people who say "I still don't get it" ever goes down. Which is why the comment about how they're not happening.