The Completely Ordinary Case of Clojure Contrib

I read The Curious Case of Clojure Contrib and unfortunately I can’t help but disagree with a lot of it. Yet strangely, I agree almost entirely with its conclusions.

I do agree with the quotes from me at the beginning. :) None of it should be surprising though. Contrib is just a bunch of libraries with a shared CA and a shared dev infrastructure. Very early, stuff like clojure.test did move from the original monolithic contrib into core and the thought at the dawn of split contrib was that might happen more, in which case having a shared CA would be helpful. I can’t remember anyone ever claiming that stuff in contrib would necessarily move into core, just that it was possible to do so if that became desirable. Some of tools.deps add-lib stuff might move into core, for example.

There are a bunch of contrib projects that are not “in” Clojure but are used in the Clojure build itself (test.generative, data.generators, test.check, tools.namespace, etc) and we’re far more comfortable depending on those as contrib libraries than relying on fully external libs when building and testing Clojure proper. We now have the opposite situation - parts that started in Clojure and got pushed out, like spec, and that scenario may become more common over time, allowing us to evolve the parts included “in the box” at a faster rate than the language itself. In all these cases, contrib is useful.

There seems to be some desire in the article to force all of the libraries in contrib to have the same role, or ownership, or use, or importance. But, they’re all different, they each have unique histories, purposes, etc. If they don’t all look the same, it’s because they’re not. What they share is: license, CA, dev model, infrastructure.

At Cognitect, we make decisions about where and how to host different libs based on a variety of factors. Whether we put things under Cognitect or Cognitect Labs or Clojure or their own orgs (like Pedestal) are decisions based on a bunch of factors - licensing, support expectations, toolset, whether we consider them to be products of Cognitect or Clojure, who’s working on it, for what purpose, etc.

Contrib projects are community projects - anyone is welcome to contribute under the rules of the project and at the direction of the project owner. Saying “contrib” is not community-driven is meaningless because “contrib” is not one thing - every project is different. Many contrib projects are run and contributed to entirely by members of the community without any involvement from the core team. Saying those projects aren’t community-driven seems disrespectful to those community members doing that work. Certainly, there are projects in contrib closer to the language that are controlled more tightly. Even those are still open to contributions. Spec or tools.deps or core.async have all had community contributions. This distinction between community-driven and community-involved is … weird. All projects have owners that make decisions.

Re “typically the projects would see activity while their original author is involved in them and would stagnate afterwards” - this is true of 99% of open source projects. The benefit of having an organization around these projects is exactly that if interest wanes or life intercedes, we can carry it along for a while until a new maintainer steps up - and this has happened many times! You say “there’s relatively thin line between stable and abandoned” but that goes the other way too - there’s a relatively thin line between stable and active. All it takes is for someone to have new ideas and ask to pick up the project again. Again, this has happened many times.

Re “the high bar to contribute has likely affected negatively most projects in Contrib”, this is imo, totally bogus. Most contrib projects have a few primary contributors and many more contributors that have provided a fix or two, which is entirely the norm across open source. The real barriers to entry in contrib projects are exactly the same as they are in any other project - getting people to know it exists, providing useful functionality, creating consistent design over time, building consensus, getting work done. Process stuff like signing a digital CA form (one minute), or making a patch file (just add .patch to a github PR url), or using JIRA are trivial compared to the people and technical parts of this work. I make patches and PRs and jiras and github issues every day and it’s all just the frame, not the work.

There seems to be a narrative that nREPL “failed” in contrib but has been wildly successful outside of it. I call BS on that. nREPL has succeeded outside contrib because Bozhidar has been a tireless cheerleader and promoter and nurturer of people AFTER it was migrated. He could have done the exact same work when it was in contrib, as others do in other contrib projects. The contributor curve since migrating looks very familiar - a few primary contributors, lots of people contributing a fix or two, just like most contrib projects. The distribution is a little wider, and that’s the benefit of a lot of people work.

Despite all these things I disagree about, I am in complete agreement that if the community wants things to exist, they should make and nurture them. That has been the message for the entire history of Clojure (it’s in the linked history article from the 2011 Conj, it’s in the etiquette newsgroup post from Rich in 2011). Whether you make things and nurture them in contrib or elsewhere is imo entirely irrelevant.

Please, go forth, make more awesome Clojure things, and tell people about them. If you want to be involved, there are an endless number of existing projects with things to fix and improve. You do not need direction, or blessings, or contrib. Just do the work that needs doing.

Written on April 23, 2019