If you take anything away from this (excellently written) article, I think it should be the above paragraph. All programming philosophies espouse creating reusable interfaces, but at least for me, the first time it really clicked and I started writing truly composable code, was when I started structuring my ideas in terms of categories and objects from abstract algebra.
It's one thing to write an interface that can act on any object that responds to a "foo" method. It's a completely different level of flexibility to support any object that behaves like a ring, or a monoid, or whatever other crazy mathematical formalizations you can come up with to describe your code. Once I made that connection, I started making fewer assumptions about my code, and as a result it's been less prone to edge cases, and magnitudes easier to test.
All of this with Ruby being my primary language, too. Fancy languages like Haskell help, but they're not a prerequisite for you incorporating these sorts of highly abstract concepts into your work.
The probably with informal speech is that it is ambiguous.
Also, using informal speech would really hurt you when generalizing these concepts abstractly. Plus after coming up with informal speech to talk about all of these things, you'd probably realize your words aren't that much different than theirs.
I'm familiar with the concept of duck typing and generic interfaces, but I'm not sure that's quite what you're getting at and I'm curious to see what an implementation of what you describe looks like.
Some researchers a lot smarter than me realized that when you're dealing with distributed systems, you're able to reliably achieve eventual consistency by structuring your data as a CRDT.
The idea is that if operations on your data types are both commutative and idempotent, nodes in a distributed system are able to arbitrary leave and rejoin a network, possibly sending duplicate messages at any point, with eventual consistency still being maintained. Since it doesn't matter with what order operations on the data types are performed, and since performing an operation multiple times has no effect on the state, you're able to guarantee that all nodes will achieve the same state after applying all pending operations - regardless of the order they're performed in.
Given the idea of a CRDT then, we know that in designing data types with eventual consistency as a goal, we can gain a lot of power by ensuring that they uphold two properties: idempotence, and commutativity. By examining our needs for that data type further, we're able to build up as complicated a structure as required. Do we need an append-only datastore? That's a commutative, idempotent monoid.
Now you're able to go and implement a commutative, idempotent monoid in as naive a fashion as possible. If you ever need to optimize it or swap out a more complicated structure, you're guaranteed to end up with a system that has the same semantics, as long as that new implementation forms a commutative, idempotent monoid. As Tel mentioned in another comment, you also end up being able to draw upon all of the laws regarding that structure. It's like implementing an interface in Java, but instead of just knowing that the resulting object supports an "append" method, you also know that the resulting object follows all of the other laws that mathematicians have spent the past 4 billion years proving.
In practice, this line of thinking usually doesn't explicitly show up in my code, but it's definitely on my mind while I'm designing out new systems on a whiteboard. My coworkers might not understand a thing about abstract algebra, but that's okay! My goal isn't to fill our codebase with mathematical jargon, it's to build small, composable interfaces, that document their assumptions, and I've found that through this process I can do that.
Category theory is very much like UML in my opinion, in that its use lies in describing systems, rather than implementing them, and I feel like this is the reason so many people are able to proclaim its virtues, while at the same time struggling to point to a specific line of code, and being able to say: "This is why category theory is important!"
I do think Kleisli categories are a better way to explain the benefit, though.