
Kleisli Categories – Composition of Logs - signa11
http://bartoszmilewski.com/2014/12/23/kleisli-categories/
======
ShaneWilton
_An astute reader may notice that it would be easy to generalize this
construction to any monoid, not just the string monoid. We would use mappend
inside compose and mempty inside identity (in place of + and ""). There really
is no reason to limit ourselves to logging just strings. A good library writer
should be able to identify the bare minimum of constraints that make the
library work — here the logging library’s only requirement is that the log
have monoidal properties._

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.

~~~
d4mi3n
Would love to see some examples of how you put these concepts into practice.

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.

~~~
QuinnWilton
My favourite example is probably CRDTs - commutative replicated data types
([http://pagesperso-
systeme.lip6.fr/Marc.Shapiro/papers/RR-695...](http://pagesperso-
systeme.lip6.fr/Marc.Shapiro/papers/RR-6956.pdf))

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!"

------
chowells
Interesting claim that a discussion of Kleisli categories isn't the place to
get into a discussion of monads, since they're identical.

I do think Kleisli categories are a better way to explain the benefit, though.

