Monads, monoids, semigroups, functors; functional programmers love to make use of this type of vocabulary to describe software, and at first glance it can seem intimidating and abstruse. Why do we need to know, as the common joke goes, that a monad is just a monoid in the category of endofunctors? And what value is category theory and related mathematics to the field of software engineering anyway? An occasional complaint I’ve seen is that this type of language is too difficult and obscure to learn and we should just stick to more “ordinary” names and concepts.
I think there are a couple different things to say to this challenge. Firstly, it should be noted that what we consider ordinary is really just a historical accident, and it could well have been that the programming and software engineering community had settled on categorical concepts from the very beginning. In which case, junior software engineers would learn from the start of their careers what it means to compose two monads together via a monad transformer. Instead the industry went down a different avenue and things like monads appear to be big and scary concepts.
Secondly, I would agree that these concepts can be challenging to learn. But generally the best things are. And moreover the reason for the challenge is that these concepts are universal. They apply across all languages (in fact, they apply across all of mathematics, but that’s not of too much concern for the programmer interested in building composable software). For example, a functor in Haskell is a functor in Java is a functor in Javascript is a functor in Go, and on and on. These concepts cross all language barriers, and yes they can be daunting at first, but they are learn-once and apply everywhere concepts. What does Haskell’s »=, Rust’s and_then, Scala’s flatMap, and Javascript’s then have in common? They might seem completely unrelated, but they are essentially the same function: they all compose monads. Once you’re familiar with these concepts you can jump from language to language like jumping from car to car once you’ve learnt how to drive.
Thirdly, and related to the second point these concepts provide a shared-basis for mutual understanding. You’ll notice that each language I listed above has different names for the same idea. Rather than re-invent new words every time we create a new language I’d think it much better to reuse shared concepts: and there really is no better language to use for shared concepts than mathematics. And category theory is the language of composition, and is really by extension the language of software engineering (a field so intimately concerned about how to compose). Of those questioning the use of categorical language and vocabulary I would really have to ask: why would we not? As a domain driven designer would say, our domain is software itself and our ubiquitous language is the language of mathematics.
Fourthly, another benefit of using these mathematical terms and concepts is that they often have a long history and etymology, which can be helpful in aiding and deepening understanding. The word “algebra” comes from the Arabic root “al-jabr” which means something like “to reunite/reunion.” So an algebra is something which reunites things. Similarly “catamorphism” comes from the Greek “kata” meaning something like “downwards” and “morph” meaning “form/shape”, i.e. “down + shape”. The root “kata” here is the one found in English words like “catastrophe”. So a catamorphism is what most languages call the reduce or fold functions, as they are taking a structure or shape and turning it into a single (downward movement) value. The reverse of a catamorphism is called an “anamorphism.” The root here is “ana” meaning “upward”. So the inverse of a catamorphism takes a single value and turns it upward into a shape/form, or unfold. Putting these three concepts together we’ve just rediscovered what are called “recursion schemes.” A catamorphism takes an algebra (a definition of how to reunite things) and performs the downward movement to a single form, and an anamorphism does the inverse. Of course, etymology is not enough by far and these concepts can take a bit of work to understand. But the trade-off is that like learning to ride a bike once we know them we know them and can apply them to all languages.
So all in all I think there are very good reasons for using the funny names that functional programmers are so fond of. We shouldn’t reinvent the linguistic wheel but should build upon the solid foundations we find at our disposal. And let’s not forget that naming is a very hard problem - a problem that is solved in this instance.