They're able to turn a lot of algorithms inside out; make the kernel a simple function of values where they used to be threaded through the code flow, and use things like bind to mix them back in. This makes algorithms testable and more composable, and raise the level of abstraction in the rest of your code so that you're operating more at the DSL level for your domain, whatever it is.
It's worth learning the concepts. Once you do, you'll be surprised that there's so little "there" there.
And their commonality and generality are exactly the reasons why they should have short yet precisely general names.
I've been using Scala full time for a couple of years now, but it took me ten months to really understand not just what monads are, but how they are useful in expressing a program from a different perspective to other approaches, and the benefits that come from that. Now I use them all the time and see how they add huge benefits to my code.
In all the time that I've been working with Scala, and building my knowledge and experience of how to apply functional principles usefully, I have yet to (knowingly) use a Monoid, or encounter a situation where it was clear that they would have a benefit. I'm not saying that there are no such situations, and it may be that there have been situations where they would have been useful, but I didn't know it, and I would love to be able to add them to my toolbox. However, I do see that a lot of the time these concepts are introduced in a very abstract way and what it missing is not the simple definition, but rather some clear idea of when, how and why to use them.
The most useful name is probably somewhere in the middle. It may not necessarily consist of everyday words, but it probably relates very obviously and clearly to the C++ functionality.
"Monoid" is a very detached term. It doesn't obviously relate to the C++ construct or concept the way that terms like "typedef", "template", "stream" and so on do for other constructs/concepts.
Monoid is NOT a detached term it says I have a type with an identity element, and an associative binary operator, and that that (id `op` elem) always is elem. Try to tell me that i complicated in the slightest. I can most definitely not give you a single line description of templates, or most C++ features. Abstraction makes things more general (i.e less specific) meaning it is easier to describe, reason about, and discuss because I can only talk about things that hold universally.
If you doubt me let's show some things that form a Monoid right now, and how easy it is to define.
1) Strings - identity element = "" - associative operator = +
2) Lists - identity element = list<A>() //empty list - associative operator = concat
and we can go on and on finding instances of Monoids simply from a one line description.
Just for the record, I'd like to state that I couldn't make heads or tails of this explanation. 'Identity element', when thinking of C++, just makes me think of a hash function or something.
Looking at the examples, it's sort of clearer— a monoid is a type that can hold a value that's empty (or zeroed, or whatever). But that doesn't change the fact that that explanation (and the term 'monoid') is so firmly rooted in math jargon that it's basically incomprehensible to someone used to thinking in C++.
It's firmly rooted in like 5th grade math. Every child in the US that takes basic algebra in school learns about identities and identity rules like "0+x=x" or "1*x=x" or in pseudocode as something like "(id `op` elem)=elem".
Possibly, C++ should adopt the name anyway, but it's by no means a commonly used or understood term by most users of C++. As has been mentioned, C++ is above all a language whose design is driven by pragmatism, so if another more common term can be found for the idea of a monoid you can bet it'll be preferred (even at the expense of some literary accuracy).
For most C++ terminology, you don't need to give a single-line description. The keyword or concept name alone generally embodies that information very well. To use your example, at a basic level a C++ "template" is quite similar to a form letter, stencil or other real-world "templates". It's a predefined mold that you inject your specific information/material into to get a final product with minimal effort.
There just isn't a direct relation back to the real world with a term like "monoid". You end up with people who are confused at best, or more likely they're thinking of some other word that sounds similar but is totally unrelated.
And that might even be a good thing. The stencil analogy for C++ templates gives you a warm fuzzy feeling, but doesn't actually help you program. Contrast: the one line definition of Monoids is all there is to them. That's all there is to know about Monoids.
Classic. Sometimes Haskell fans have useful things to say, and sometimes they're just using terminology to try to win an intellectual dick-size war. The tricky part is telling the two apart.
Imagine trying trying to describe a monoidal category or topoi in the OOP style, it's like trying to describe what a Fourier transform is to someone who insists on using roman numerals.
Or describing Latin declensions to someone who reads kanji. The key is that, if the audience admires Latin speakers, you can appear smart.
Such as?
"Monoid" is a very detached term. It doesn't obviously relate to the C++ construct or concept the way that terms like "typedef", "template", "stream" and so on do for other constructs/concepts.
Well of course! Monoid is far more general than those other concepts. It's also a far better name, being unambiguous. Those other names are reused all over the place in different contexts and their meanings subtly shift between their uses. Monoid is not so overloaded; once you learn it, you know what it means every time you encounter it.
However, I would like to think that there's somebody out there who could come up with a name that describes the concept sufficiently, while still using pragmatic C++-style terminology.
All I'm saying is that "monoid" is terminology of a style that's very different from basically all other C++ terminology. To many C++ programmers, even those with a background in mathematics, it's no better than gibberish.
At least the existing C++ keywords and terminology tend to be far more descriptive of what they're referring to, even if there is ambiguity in some cases. This is true even for the more abstract concepts in C++.
What does that mean? How is it any more detached than object or method?
An "object" is something specific that exists (implying it can likely also be created and destroyed), and can be distinguished from other objects. This applies equally well to a combination of a data structure and some related code as it does to a tennis ball, or to a car, or to a book.
A "method" is a systematic way of doing something. That "something" could be the operations described by some source code, or it could be tying a shoe, or even brushing one's teeth.
"Monoid" has no good real-world parallel. It has no related or relevant meaning outside of very, very specific contexts. That's what makes it "detached". It's off on its own, with an isolated and non-obvious meaning.
It's jargon, but it's jargon shared across a few fields, which makes it more worth learning. And while it lacks a "real-world parallel" it has a lot of simple examples. Lists over concatenation, integers over addition, positive integers over max, negative integers over min... It's interesting and informative to observe why integers over max (or min) is not a monoid but is a semigroup.
The Haskell people share your concerns. Simon Peyton Jones famously suggested "our biggest mistake [in designing Haskell was u]sing the scary term 'monad' rather than 'warm fuzzy thing'". (https://research.microsoft.com/en-us/um/people/simonpj/paper...).
Also, this objection would seem to apply equally well to functions and variables as monoids.
And the same holds true for "variable". It's a very common term for things that change their state of being, including stuff that isn't directly related to programming or mathematics. Stuff like the weather, somebody's mood, and so on.
"Monoid" just doesn't have any everyday meaning like those terms do, especially a meaning that so closely resembles the programming concept like in the case of "function" and "variable".
Monoid, on the other hand, has no such problem. If you look it up, its meaning in mathematics directly translates to its meaning in Haskell.
Yeah, they mean yet something else in statistical software.
Most people are inherently familiar with the concept of a "container", in the sense of something that holds other things, regardless of whether it's a physical container or a data structure.
"Iterator" might not be as clear as "container", but at least most people are familiar with the concept of doing something repeatedly, whether it's some physical action or executing some chunk of source code.
"Monoid" just isn't like that. It may be concrete when constrained to the context of mathematics or programming, but it's quite meaningless outside of those very specific contexts.
But that isn't really true. Addition and multiplication are both real-world examples of monoids that everyone is familiar with (obviously, these aren't physical things, but I don't see why that's relevant).
DRY is not abour reusing names from other fields. Perhaps you were going for the "principle of least surprise".
But given that most people are not familiar with those Math names in the first places (including mathematicians not versed in type theory, trust me, I've asked a few Math colleagues from university and it's chinese to them too), I doubt even that applies here.
So, no, some arbitrary names like Monoid and co, obscure even for people with a passable Math knowledge, picked back in the day, is not the best naming scheme for that behavior that people can come up with.
The best that it has going for it is that is has been used in Math "for the last 50 years" (still, hardly a "staple").
A lot of math naming and notation is arbitrary and a historical accident. That was one of the things the "axiomatic language" guys tried to solve back in the '20s after all.
Many computer scientists already understand reasoning about abstract structures and use them in their work.
For example commutative operators are incredibly powerful tool in distributed systems, as I am able to disregard ordering. In general it is useful to be able to say that if I meet an abstract specification (i.e a Monoid, Group, Ring, ect) because it allows me to perform operations with confidence that they are correct.
If you doubt the usefulness of this just look to Twitter (can't get much more "real world" than that) and see how they have been leveraging abstract reasoning in projects like Summing Bird (and its sub-projects like Algebird, Bijection, ect).
Well, I asked undergraduate math students on their final year, and they didn't know. Perhaps all PhDs in math do, but that's not much of an argument in reusing those terms in CS.
Myself had several classes of algebra in different years in university (for the CS degree) and we didn't ever talk about Monoids and such.
I have no reason to not believe you, but how is this possible, and what does it say about either those students or that university or even both? Do they also not know what a group is? A ring, a field? How can a mathematician (and a nearly graduated student in maths is certainly a mathematician) not know what basic algebraic structures are? I'm shocked, frankly. It's literally equivalent to saying they don't know what real numbers are, without exaggerating one bit.
They should know what a group is, because even us, CS students, were taught group theory for a whole semester.
As for the monoid thing, I guess they could have been taught at some point, along with being taught 20 other branches and fields of mathematics in different classes, and they were more likely to remember a) the basic stuff, b) the stuff they started to specialize on and concentrated upon writing their thesis. So, I guess if I had talked to someone who had taken a preference to type theory and such, they would have known.
>How can a mathematician (and a nearly graduated student in maths is certainly a mathematician) not know what basic algebraic structures are? I'm shocked, frankly. It's literally equivalent to saying they don't know what real numbers are, without exaggerating one bit.
Is it? I don't know. You can read whole books in Algebra and not mean the word "Monoid" once in them, including some university books.
For example (not even one mention): http://www.amazon.com/gp/search?index=books&linkCode=qs&keyw...
This again no mention: http://www.amazon.com/gp/search?index=books&linkCode=qs&keyw...
This (a "graduate level" book) only mentions Monoid once, somewhere on the first pages, and adds that it won't be emphasised: http://books.google.com.sg/books?id=C4TByeUh9A4C&printsec=fr...
And I'm pretty sure in our Algebra books (for CS students, 2 classes in the 1st and 2nd year) there was no much mention of monoids (or, possibly, the professor skipped over those chapters, maybe had some brief explanation and went on to other things).
Of course, what university gradutes of a field do not know can sometimes be even more daunting. For example, a surprising percentage of degree-ed Computer Scientists cannot even solve the fizz-buzz problem:
Hm, I just gave a quick glance to one group theory textbook (the only one I have in English), and to be honest in the first 20 or so pages there is no mention of the word "monoid" (as far as I can see, I really just quickly scanned through the first chapter) but it does mention semigroups (which are just an identity element away from monoids)...
> And I'm pretty sure in our Algebra books (for CS students, 2 classes in the 1st and 2nd year) there was no much mention of monoids (or, possibly, the professor skipped over those chapters, maybe had some brief explanation and went on to other things).
Yeah, and that's fine, but for maths students to not even remember that it was mentioned is kind of sad. It shows they don't really care that much about what they're doing. If it wasn't even mentioned by the professor, shows a disinterest on his/her part to actually teach concepts. It's always much better when teaching a concept to also at least mention related concepts or similar ones at different levels of abstraction, that gives a complete picture in which you can neatly place things. A group doesn't just appear out of nowhere (although it certainly can be defined on it's own), and it's not alone...
> For example, a surprising percentage of degree-ed Computer Scientists cannot even solve the fizz-buzz problem:
Sigh... I know. But you see, that's why I found this discussion about the unintuitiveness of the word "monad", here of all places, absurd. I wouldn't expect people who cannot solve fizz-buzz to have any clue about anything, and on some level I'm fine with that, this is not an elitist rant, but people in a place like this? After all, programming routinely involves dealing with concepts that are much more unintuitive that a monoid, IMHO.
Edit: Yes languages get this wrong but I was focusing on the borrowing of vocabulary more so than the correct usage of it. Many words are abused like Functor to mean function object in C++, functions referring to procedures, ad-hoc vs. parametric polymorphism, strong and weak typing ect.
Oh, and lots and lots of your peers are formed in an specialization of mathematics called "Computer Science".
One might as well say that biology is a branch of philosophy, because it was the source of all the natural scientists; but such a description, in modern times, would not be particularly informative.
Some of those words are very likely non-mathematical words that were adopted and re-purposed by mathematicians. "Tree" is inspired by how the data structure's shape is very similar to that of trees (that is, the plants), for example.
I think the abstract algebra names are great because they describe the general case precisely without any preconceptions carried along with them.
And there's papers about interesting things you can do with them.
I mean, some concepts are clearly not able to be explained to the layman; you need some background. But do people really need to learn abstract algebra to be able to get their heads around this stuff? Are there no better terms that communicate to more people?
And, given that that's the problem, clearly dog breeds are not the answer either.
I'm not a C++ programmer; I don't know what half the names are from the GoF book. Does that make them bad names? No! Since when should a word have to carry around its own definition so that people who've never seen it before automatically know what it means?
I mean, some concepts are clearly not able to be explained to the layman; you need some background. But do people really need to learn abstract algebra to be able to get their heads around this stuff? Are there no better terms that communicate to more people?
Concepts like Functor and Monoid and Monad are extremely simple. You don't need to go back to school to learn them. You only run into trouble if you expect them to be explainable by analogy to a more concrete notion.
And, given that that's the problem, clearly dog breeds are not the answer either.
It was a sarcastic remark but it highlights an important point I want to make. Assuming you knew nothing at all about dogs; if you were given a list of dog breeds and a stack of photos of dogs, would you be able to match the breed names to the photos? No, probably not. That doesn't mean their names are bad; you simply lack the experience to figure it out.
>Concepts like Functor and Monoid and Monad are extremely simple. You don't need to go back to school to learn them.
The issue here is not at all how complicated the concepts are. The issue is how common and/or descriptive the name for them is. "Monoid", to someone who hasn't studied abstract algebra, is neither. Something like "Appendable" might be more appropriate for C++.
Oh come on, man! I can't believe this ridiculous discussion. I'm not lashing out at you, don't get me wrong, but seriously, you think you need to study abstract algebra to understand what a monoid is? Um, I remember one of the first things mentioned in the, literally, first lecture in undergraduate course on calculus was a monoid, among other algebraic structures. Granted, it was theoretical physics, but still, I doubt any respectable university teaching CS would fail to give students at least some familiarity with basic algebraic structures. But you don't even need a university education to grasp this, seriously, stop being afraid of precise terms, there's nothing scary behind them.
EDIT: And to actually address your point :), "intuitive" can only go so far. Sometimes there is simply no intuitive term that can do justice to the concept at hand. As Feynman once said: "I'm not going to lie to you, I'm not going to tell you it's like a ball bearing on a spring because it isn't." Especially in programming I'm not convinced that intuitiveness of a mere label for something is a valuable goal. You can't program on intuition, at some point you just have to learn how the thing really works.
No no no. My whole point is that while the concept is not complicated, that particular term ("monoid") simply isn't common.
I agree with your edit section though. And I don't necessarily think C++ shouldn't adopt the term 'monoid' due to its relative obscurity (especially if no better term can be found); I just think it's got some figurative points against it for that reason.
So I can append False to True to get False (Boolean monoid under &&) or append 8 to 9 to get 72 (integer monoid under multiplication)? There's also a monoid instances for any single-argument function into a monoidal type, where (f <> g) x = f x <> g x; I don't know what to call that but it's definitely not appending.
Append is a name that works in a few cases but horribly breaks down in the general case.