I'm kind of surprised no one has said this, and I'm kind of a novice, so I'll probably get it wrong.
To me, the interesting thing about category theory is that it draws out the significance of relationships in a system. We often spend a lot of time thinking about the things, themselves, in a system.
- What are their properties?
- What do they mean?
- What is their identity?
In category theory, almost all the significance of individual things is erased. Instead, you often group things up into sets and other structures, and then call the whole set an object. Then you think about the existence of morphisms from one kind of object to another. A morphism is kind of like a function, in the sense that something goes in, and something else comes out. Except that we're not concerned about the properties of what's going in and coming out, so the function body doesn't really matter. A morphism is something more general than any specific function. It's more like a function declaration--specifying that something does exist without saying anything concrete about what it does.
So, you're operating on a level of abstraction that removes basically all unnecessary details about things and relationships, other than existence and some basic rules for how those relationships can be composed to form new ones. As it turns out, there's a whole lot you can say and prove about categories once you know a bit about their structure.
In my opinion, the real power is that any given system can often be "projected" into categories in a multitude of different ways, and depending on the structure of those categories, you can say apply proofs from category theory to say interesting things about that system.
Going further beyond that, category theory concerns itself with how categories relate to each other, by considering categories themselves as objects and relationships between them as morphisms.
Why does this matter to programmers?
Well, we often want to design systems that are predictable, no matter what the actual identity of the data that traverses them. This is abstraction, and we do it on many levels, all the time. We also want to chain together our abstractions. This combination of abstraction and composition is something category thoery is well suited to analyze.
I'm probably off here in some important ways, but this is my layperson's takeaway from spending some time trying to understand what all the fuss was about.
To really drive the point home of the level of abstraction I like to think of a category of domino tiles.
It kind of makes a few things apparent.
Tiles would be the morphisms and objects would be the number spots on the tile ends.
So the first insight: morphisms is the actaul object of study. The “objects” of a category is just a consequence of how the morphisms may, or may not, compose.
My first hurdle when learning things was being distracted by trying to understand what objects where, some times they would be types, sometimes sets, and it was never really clear what their cardinality would be. As if the theory hid important details that you had to keeps track of implicitly. But it doesn’t, objects really are inconsequential, they are just there to be a place for morphisms to meet, nothing more. Just like the number of dots of the domino tiles. We could have used color instead, and the tiles would compose in exactly the same way.
Second intuition, there’s no computation or anything else going on. Just as you say about the functions. The only thing of concern are the composability of those things called morphisms, be they functions or domino tiles.
In the lecture series linked a few places in this thread, Bartosz makes a fantastic point of this when deriving some properties of surjective and bijective functions using only composability.
To me, the interesting thing about category theory is that it draws out the significance of relationships in a system. We often spend a lot of time thinking about the things, themselves, in a system.
- What are their properties?
- What do they mean?
- What is their identity?
In category theory, almost all the significance of individual things is erased. Instead, you often group things up into sets and other structures, and then call the whole set an object. Then you think about the existence of morphisms from one kind of object to another. A morphism is kind of like a function, in the sense that something goes in, and something else comes out. Except that we're not concerned about the properties of what's going in and coming out, so the function body doesn't really matter. A morphism is something more general than any specific function. It's more like a function declaration--specifying that something does exist without saying anything concrete about what it does.
So, you're operating on a level of abstraction that removes basically all unnecessary details about things and relationships, other than existence and some basic rules for how those relationships can be composed to form new ones. As it turns out, there's a whole lot you can say and prove about categories once you know a bit about their structure.
In my opinion, the real power is that any given system can often be "projected" into categories in a multitude of different ways, and depending on the structure of those categories, you can say apply proofs from category theory to say interesting things about that system.
Going further beyond that, category theory concerns itself with how categories relate to each other, by considering categories themselves as objects and relationships between them as morphisms.
Why does this matter to programmers?
Well, we often want to design systems that are predictable, no matter what the actual identity of the data that traverses them. This is abstraction, and we do it on many levels, all the time. We also want to chain together our abstractions. This combination of abstraction and composition is something category thoery is well suited to analyze.
I'm probably off here in some important ways, but this is my layperson's takeaway from spending some time trying to understand what all the fuss was about.