Hacker News new | past | comments | ask | show | jobs | submit login
Category Theory abstractions for Clojure (funcool.github.io)
76 points by michaelsbradley on May 1, 2015 | hide | past | favorite | 18 comments



What is the value of Category Theory for programming? I'm genuinely interested, as my knowledge about this subject is little to none.


Category Theory is all about composing things and being able to reason about them mathematically. In programs, we compose lots of things (functions, types, objects, systems...), and being able to abstract that away is valuable. Bartosz Milewski has been putting together a nice series ("Category Theory for Programmers") for a little while now, that seems to be pretty well-received and may give you the answer you're looking for: http://bartoszmilewski.com/2014/10/28/category-theory-for-pr...


Thank you. I've just finished the first chapter and it has been a pleasant reading so far. The mapping of "real world" onto Category Theory surely makes the matter more approachable.


Category Theory is about the fundamental similarities between superficially different constructs, so is very applicable to programming (which is really all about abstracting commonality/patterns from things). It suggests abstractions that can apply to a wider variety of programming problems. E.g. I wrote a "survey" of effect handling in a few languages recently, http://m50d.github.io/2015/04/21/effects.html ; almost all of those examples can be handled with a monad or similar abstraction.

Coming at it from the other, "pragmatic" end, in http://m50d.github.io/2013/01/16/generic-contexts.html I abstract out a particular interface from two similar problems, which turns out to be that of an Applicative Functor.

Once you have these constructs you can use theorems from Category Theory to tell you things about them, but honestly I found the most useful part was having this "library" of standard abstractions - almost like design patterns really. More immediately there's usually an actual library of functions that you can use on your own types. E.g. by defining a Monoid instance for my Stats class, I can foldMap a list of things to get the overall Stats for the whole list.

More complicated example: I have two reports which are fiddly and client facing, but have some code in common. So I have a parent class and two subclasses, but the control flow goes back and forth between them; in particular there's a point where the parent class needs to loop over a list, calling a subclass-specific method for each element.

Trouble is, those methods need to do slightly complex things. For one client, we get that part of the report from a web service, so we need to make an async HTTP request for each element (blocking for each call would make it terribly slow). For another client, they need to accumulate Stats for each element in the list and put them together for an overall Stats.

Both these things can be hard to treat as a "normal" method call. We could e.g. keep the Stats in a global variable, but that would be confusing to debug and hard to maintain. We could have some service that pools HTTP requests, maybe, but this would be extra code and again it would have to act as a pseudo-global variable.

But Monads are the abstraction that lets me treat both these effects the same way - and crucially, to handle them with "ordinary", refactor-safe values, at no risk of spaghetti code. The superclass is generic in the "context":

    abstract class AbstractReport[F[_]: Monad] {
      def perUserStep(userId: UUID): F[UserResults]
      ...
      def sendFinalReportToClient(finalReprort: F[Report])
    }
and then in one subclass perUserStep returns a Future[UserResults], and in another it returns a Writer[Stats, UserResults]. The parent class can do the generic parts of the report working with either of these things generically, using the Monad abstraction; the subclasses just have to implement sendFinalReportToClient in a way that "unpacks" the "boxed" report in a context-specific way.


Thank you. This is a lot of information to digest! But I think it helped me to see the beauty of this. When we map our programs into these well understood abstractions (monads, functors and stuff), we get for free means of combining them and handling them in very generic ways.


It seems like within a week of me trying in earnest to adopt Clojure as another language in my arsenal, HN starts having a lot more regular Clojure visitors to the front page. Is this just confirmation bias, or does it seem to other HNers like Clojure is getting more traction and attention these days?


Clojure certainly seems one of the darling languages on HN (along with Haskell, Rust, Go). The thing that _I'm_ noticing all of a sudden is the uptick in articles on category theory -- which, similarly, I was only made aware of about 3 weeks ago.

Is there a graphical representation somewhere of buzzwords appearing on HN over time? If not -> hack-a-thon project.



I was feeling that too, but I'm guessing it's just a matter of paying attention from having an interest. I notice the same thing when I move to a new city: I move to San Francisco and it seems like everyone's talking about SF in my reading; I move to Boston and it's the same thing.


A big clojure conference happened last week (http://clojurewest.org/). That's probably spurring a lot of conversation.


Neat. You should know that cats is also the name of a Scala library [1] that includes a lot of similar concepts.

[1] https://github.com/non/cats


Not a great deal of explicit category theory in this. Somone ought to implement Moggi's paper on exceptions and show exactly what the constructions mean.



Yes. Many category theorists would find Moggi91 opaque. It could benefit from commentary and more detail than would be standard for a published paper, if the intention is to make the categorical semantics of functional programming with side effects accessible to a wide audience. I guess one could suss this out of Robert Harper's book on the foundations of programming languages, but I was thinking of something more direct.


The "monads" library they ding for not-great documentation is https://github.com/bwo/monads/ (the documentation is admittedly not great).


Exciting! I was looking for a ClojureScript monad library just last month. Can't wait to dig in to this one.

I think there is a lot of potential to help with the complexities of asynchronous failures.


I wish the author didn't make the same mistake as Haskell by calling it return. But i guess it has become convention now.


Yeah. I guess "return" is still an improvement on the previous name, η. :)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: