I am currently quite into category theory, and I've been thinking and writing quite a bit about what value it brings to me as a programmer. I think this article (and many articles) about category theory and the abstractions it "introduces" are missing an important point: abstraction is first a tool for thinking.

One thing often missing from "let's rewrite something with some design pattern" articles is that many different ways of writing something that on the surface seems like the same code are valid. If you are writing golang because that's what the team uses, you can be as extraordinary a functional programmer as you want, the `if err !=` style is going to be the best, simply because that's how your team communicates. If you are on a team of haskell programmers that all know how to instantiate a Monad typeclass, use Monad.

The value of knowing the concept of a monad is that mentally, you can think of both ways of writing the code as the same: chain things together repeatedly with the next step somehow being related to the previous step. When I write `if err !=`, which is my preferred way of doing this kind of error handling, I still think of it as a monad. If I want to refactor this method in terms of saying, passing in an object that counts the types of errors for the purposes of telemetry, I know that this is equivalent to lifting a state monad into it, at least abstractly. That I in practice then pass in a mutexed global object or actually use some liftM / monad transformer machinery doesn't change my thinking.

The way I think of abstraction now is that it has two directions.

One is seeing the abstractions, being able to boil down a concrete instance into a more abstract concept, by forgetting the details. By doing that, you then have the option to do some more interesting, powerful logic on it. You can use further concepts to maybe uncover new properties. You can shortcircuit complex refactors by mapping them to a simple transformation in this more abstract space.

The other direction is transforming your abstraction back into something concrete. You don't have to use a language that allows you to formulate things at the new abstraction level, although it's cool if you can. But you can totally write functors in C, in fact everybody does anyway. More importantly, when you do that transformation back from abstract-land to concrete-land, you can take a lot of shortcuts as a programmer. It's cool that you can do all kinds of fancy stuff with a pure function, but if I want to use a mutating function to encode my functor and it works in practice I can still think of it as a functor for most cases.

One concrete example I wrote about earlier today, which is the concept of a product in category theory. It's a very abstract idea, if you have these morphisms and these objects and you can do this and that then it is called a product. The usual approach is to then say "and that's what tuples and structs are" and moving on, but it falls way short of what I think this gives us. It personally allows me to see that if I have a function that parses a string into a date, it's fine for me to say, store a date as a string, because it's abstractly equivalent. If it sounds obvious, it's probably because that's an abstraction you have spent time already forming and internalizing, but probably didn't have precise mathematical language for it that now allows you to mine a huge swath of mathematical literature for further cool tricks.

https://write.as/mnmlmnl/the-value-of-category-theory-for-a-...