Couple of years ago i’ve irreversibly switched from ruby to clojure and one of the key motivations was the mean size clojure libraries — it was extremely small while solving the same problems. We’ve been crafted 0.5M SLOC ruby project for 6–7 years, that’s time and amount of code comparable with labor spent on framework/libraries and that’s when you are not writing code on top, but fill and know your system and your stack as a organic whole. During this time you are in-lining and extracting libraries from/into code-base. And that’s was quite painful to discover “incidental implementation complexity” most of them (including our own).

For me the very attractive side of ruby community is elegance and humanity of libraries design and that’s why such a small community had a huge influence on the whole industry. But things not so good inside, in implementation code, which some times really awkward. And this is not the only ruby problem, from my point of view, this is problem of most of imperative & OOP languages. This paradigm gives you to much freedom and does not gives you enough clean guidelines. You are constantly lost following dispatching chain through strange entities looking for the meat.

It was amazing to discover internals of clojure libraries. Typical clojure library is no more then ~10 files with 100–500 SLOC each, properly focused on solving one concrete problem. And it’s important, that you can read, understand, fix or in-line such libraries into your project within hours or days. It was interesting experience to see the last commit for some libraries several month ago and understand that library is not dead — it’s just done. And this situation is very similar to “unix utilites”: a lot of them were touched many years ago, but work and nothing to add.

So why?

Let’s explore the unix way: here we have uniform interface to glue utilities together — it’s just exec interface and piping stdout into next stdin. This allows you to create very problem-focused utils and then compose them into something you need.

What is the clojure way?

Clojure also has “least common denominator” and this is clojure’s “Rich” data-structures. It’s common for clojure library to expose just one top level functions as API (honeysql, ring, garden, prismatic schema), awaiting/producing generic data-structure of specific shape.

That’s why it is so easy to glue clojure libraries together by just providing output of one library function result as input for another. And following authors of “Why functional programming matters”:

The ways in which one can divide up the original problem depend directly on the ways in which one can glue solutions together

that’s why clojure libraries could be kept small and precisely focused on problem, bringing to you pragmatic “simplicity”.

The small joke for ending: OOP was invented, because there was no good implementation of hash-map at that time.

73’s nicola