On helping clojure.core

There is a lot of talk about how hard it is to contribute to clojure.core, and also quite a lot of reasonable arguments on why it’s hard. I don’t want this topic to dwell on the ongoing discussion, so please help me out here :slight_smile:

My background comes from Python, Objective-C and a little bit of Elixir. All different languages with different governance models. I’ll try to highlight here how these languages differ in how they are developed, in the hopes that it might help propel the discussion a little bit forward, and actually allow people to help clojure.core in areas where they want and can take help. There is a lot of information already out there about this, and I aim to gather it in this thread.

I’ll start with examples of other languages:

Objective-C

The easy one first – Objective-C is (now) developed and governed by Apple, and until Swift came along it was the only game in town if you wanted to target mac/iOS platforms. No transparency, no community input, developed in the shadows and every now and then you’d get a major release, WWDC presentations, documentations, book updates etc etc.

Python

Python used to have a BDFL but recently he stepped down after 20+ years of involvement.

There is an extensive developer guide here: https://devguide.python.org

The bug tracker is powered by Roundup and can be found here: https://bugs.python.org

To contribute, you need to sign a CLA so that the PSF can use your code. PSF is a software foundation that owns the copyright of Python (transferred to it from the BDFL).

There used to be a patch-driven workflow but these days Github PRs are used.

There is a standard process for major additions to the language, called PEPs (Python Enhancement Proposals). The main concept is that you float an idea to the python-dev list, and if it doesn’t get shot down there, you are asked to write a pretty comprehensive PEP that covers problem statement, rationale, alternatives considered, impact on existing code etc etc. Various groups of people shepherd the process (editing, requesting for more input etc etc) but the final decision to reject/accept the PEP rests with the BDFL (or his chosen assignee).

For smaller things, such as additions or fixes to the (wide) standard library there is a well-established process that involves numerous people. Examples are triagers, reviewers, “nosy people” who might be in
the issue etc.

Triagers are people who can change the status/type/etc of issues. You gain this role after demonstrating your ability to help and to collaborate with others.

Triage and Code Review is usually the bottleneck. The dev guide says that you should wait a month until a code review, and then you can ping the issue to get a reminder. No one is paid to do code reviews.

There are many gentle reminders that getting your contribution in is hard, and might still be rejected after lots of work.

There is a also a dedicated security communications line for CVEs etc.

Elixir

There is a core team of 6 people, one of which is José Valim, Elixir’s creator. The development guide lives here: https://elixir-lang.org/development.html

GitHub is used extensively, both issues and PRs. Longer discussions happen on the elixir-core mailing list. Before proposing a big change to the language, you are advised to gather community feedback on forums etc, then write it up on the mailing list.

There seems to be a policy of aggressively fixing/closing issues posted on GitHub. Issue response time is also very fast. There doesn’t seem to a well-documented process. José seems to be doing a lot of triaging work on GitHub issues. It appears he is full-time employed just to work on Elixir.

It is pointed out that since Elixir has macros, you can use them to extend the language without changes to the core. The core team focuses on things you can’t do with macros, and “best-practice” features/concepts that gain leverage by being in the language itself.


To be continued. I’d love to hear how other languages deal with this. Please, let’s not use this topic to judge – just facts.

6 Likes

Stu Halloway gives a list of several ideas for contributing to Clojure as a whole, if contributing to clojure.core is not your cup of tea, and it is certainly where most of the work is:

  • Build cool applications.
  • Make libraries (Clojure is a Lisp, most of the work is in libraries anyway).
  • Write documentation and tutorials.
  • Teach.
  • Go to conferences and user group meetings.

[Source: https://gist.github.com/halgari/c17f378718cbd2fd82324002133ef678#gistcomment-2768338 ]

Some more ways, in some cases only giving specific examples of activities suggested by Stu:

  • Creating code examples on http://clojuredocs.org
  • Writing articles on how you applied Clojure to various applications and problems.
  • Participating in chat session like IRC, Clojurians Slack, or Clojurians Zulip and helping others learn how to do things.
  • Look through the issues labeled “help wanted” for the Clojure web site here: https://github.com/clojure/clojure-site/issues

Thanks @andy.fingerhut, I has about to search for that quote myself :slight_smile:

One notable thing that I remember from the Python days is the concept of post-conference sprints. Where a large room or two would be reserved, and projects (including core) would double down on clearing backlogs with the help of whoever showed up. There have also been online versions of those, where some kind of process helped people to contribute a little bit of their time.

I’ve never been a part of those sprints, but my understanding is that they were almost always triage, trying to reproduce the failure, writing a test and moving on, thus letting the core maintainers focusing on the actual solution.

1 Like

I have not heard of such an activity for any of the Clojure projects managed via JIRA tickets on https://dev.clojure.org/jira/browse/CLJ, at least none announced in a public channel. Everyone in the world is of course welcome to comment on a JIRA issue at any time, including doing the things you suggest, or writing a patch, etc.

It’s also worth considering that there are three “levels” to contribution in the Clojure world:

  • Clojure “core” (everything that ships in the Clojure JAR + spec + core.specs) – very tightly controlled
  • Clojure “contrib” – various project maintainers, still uses CLA and JIRA/patch process but more relaxed than “core”
  • Everything else – which ranges from near free-for-all to tightly controlled, nearly all on GitHub, nearly all accepting Pull Requests

Most documentation falls into that third level as well (although clojure.org is a hybrid: requires a CLA, but accepts PRs, controlled by the core team, but somewhat more relaxed than “core” itself).

That third level is wide open for anyone to contribute in all sorts of ways. On the other hand, the first level is very tightly controlled to provide us with stability and quality – it’s what makes everything else in Clojure possible.

4 Likes

Stu in his Open Source Stewardship talk slides lists 3 things:

Accretion
Relaxation
Bug bashing

It’s fairly obvious now that the first two will remain tightly controlled, and should in fact be moving very slowly to avoid breakage or unintended consequences, but I hope that nobody objects in bug bashing be as fast as possible. Of course there are nuances on how to fix a bug, and some simple bugs might have huge consequences and are best left unfixed until they are fixed properly. Are these the only bugs left? I’ve no clue, but it would be good to have the data.

There are 650 open tickets for CLJ. I wonder if some crowd-sourced triage would save the core team in the short or the long run. And/or if a group of people volunteered to be the first line of response (i.e. checking if a reported bug can be reproduced, asking for more feedback, assigning a label, paging someone).

All in all, I’d like to flip the question around – apart from the already mentioned things, how else can outside contributors help the core team deliver their vision?

1 Like

It’s important to add some nuance around that “650” number. There are really 3 buckets - defects (broken stuff), enhancements (extending existing things to do more), and features (new stuff).

I try to push as many defects with good descriptions and patches through the process in every release and there are currently about 235 open defects (here they are, sorted by # of votes descending: https://dev.clojure.org/jira/secure/IssueNavigator.jspa?mode=hide&requestId=11006). Another “weighted” vote report is at https://jafingerhut.github.io/clj-ticket-status/CLJ-top-tickets-by-weighted-vote.html.

If you want to help:

  1. Vote on important defects to fix. You will notice that the highest open defect has 12 votes. More than half of the defects have 0 votes. (There were higher voted ones but we try to fix the highest every release.) This is a vital, important, and currently mostly absent form of communication back to the core team - tell us what is causing you actual problems in your work and we will prioritize fixing those.

  2. Make ticket descriptions great (see https://dev.clojure.org/display/community/Creating+Tickets) - add a short repro, describe the problem, describe alternate solutions, etc.

  3. Make patches - see https://dev.clojure.org/display/community/Developing+Patches

There are also many enhancements (https://dev.clojure.org/jira/secure/IssueNavigator.jspa?mode=hide&requestId=11008) and features (https://dev.clojure.org/jira/secure/IssueNavigator.jspa?mode=hide&requestId=11601). Voting on those is more fun but also (in our estimation) less critical than defects. Features are often big things that we are going to look at infrequently, and frankly many of these will not be included. We do try to consider a reasonable number of enhancements with good descriptions and good patches in every release - having these in great shape to review, and supported by votes, makes it far more likely they will move forward. If it’s a perf enhancement, gather data and include the benchmark and results in a digestable way.

In many many cases, you could make the enhancement or feature outside core … and maybe you should. :slight_smile: If you think it should be in core - provide evidence! Find N alternate impls spread around the ecosystem, or a strong justification why it should be “in the box”. We still may disagree, but gather the evidence, so we don’t have to.

18 Likes

Disclaimer: I’ve worked professionally in open source (for both vendors and Foundations) for more than a decade, and was a consumer of, and contributor to open source for a decade or two before that, so I am sure to have numerous unconscious biases…

What @orestis said (“I hope that nobody objects in bug bashing be as fast as possible”) deeply resonates with me, at least as it pertains to community contributions to the first level identified by @seancorfield (Clojure “core”). I’m not going to focus here on Sean’s other two levels since:

  1. Level 2 (Clojure Contrib) has never really made any sense to me - to my mind it’s just a special case of level 3 that only exists as a historical oddity unique to the Clojure community.
  2. Level 3 is the usual open source ecosystem around a core product, and each project in that ecosystem individually lives and dies based on the maturity, diligence, and energy of its maintainer(s). I don’t think the core Clojure team should (let alone would want to) get involved in that ecosystem - this may be where Foundations might eventually make sense, but that’s a separate topic for another time.

So with that context outlined, and focusing in on level 1, my view is that fixing bugs in the core of any product is often time-consuming and almost always unrewarding work, and the easier the core Clojure team can make it for the wider community to help lift that burden, the greater the benefit for everyone (not least of all the core Clojure team, who can move from a “we have to fix everything ourselves” mode of operation to more of a “stewards of the code base, and trusted, impartial reviewers of contributions” mode).

My contention is that the current situation in this regard is far less than ideal, and that that’s turning away both potential casual contributors and regular contributors alike, which is problematic for the long term viability of core Clojure and should be cause for concern for the core team (especially because it’s so hard to quantify that lost opportunity - opt outs are mostly invisible).

Specifically:

Governance
Right now it isn’t at all clear how issues raised in the Clojure JIRA are triaged and categorised, and while to some extent this is minutiae, what does matter is that the team responsible for this are perceived to be trusted, impartial, and (when necessary) can justify their decisions (especially in the case of “line calls”).

For example, I’ve seen cases of Clojure JIRA bugs being recategorised as enhancements and then punted or closed as “won’t fix” without much (or any) public enquiry with the contributor of the bug. Regardless of what actually happened behind the scenes between the core team and/or that contributor, to the casual community member observing from the outside, the optics on this are pretty suspicious. The result of this over time is that community members may not feel inclined to “waste time” raising bugs they’ve discovered if they don’t feel like they’ll get a fair hearing.

Clearly documenting how these things are done up front, and then (ideally) automating as much of this as possible helps create an atmosphere of neutrality, which in turn fosters trust, but it’s about more than that - it’s also about how you support and enable your community so that they can become a reliable source of high-quality issue reports and (ideally) fixes for those issues.

Technical
The current “attach a patch file to a JIRA” contribution workflow is completely unjustifiable given that substantially better approaches (i.e. pull requests) are standard practice elsewhere in the open source world. In addition to the workflow benefits for contributors, most modern source code control systems (e.g. GitHub) also make it easy to automate administrivia such as CLA checks, which benefits the core team as well.

Building on the previous point about optics, uncharitable observers might interpret this as a deliberate choice by the core team to make it difficult to submit contributions, which again undermines trust across the board.

tl;dr
Ultimately I think the core Clojure team would be well-advised to engage the services of an expert in community building and management, to help:

  1. Clearly articulate what (if anything) they want from the community in terms of contribution to Clojure core.
  2. Straighten out what is currently an opaque and, bluntly, painful part of the Clojure ecosystem, and which, ironically, stands in stark and unfortunate contrast to the technology itself.

I’ve previously worked with Jono Bacon on exactly this topic, and can recommend him unconditionally (note: other than being a satisfied former customer of Jono’s I have no other relationship with him). He’s part of an informal network of similar open source folks who helps organisations of all kinds figure this stuff out, and engaging any of them would be a positive and welcome sign.

4 Likes

I am just posting some links here as I think not all commenters here know about them and it might clarify a few things:

To clarify, I had read both of the links you posted well before seeing this post. Neither of them address the points I’ve raised.

[edit] my apologies for cluttering the thread - I didn’t realise Clojureverse wasn’t threaded and that my reply to @nenadalm would become top-level.

They have been through this argument many times. They much prefer patches and jira. These arguments have been heard and decided. They most certainly are not “unjustifiable”.

3 Likes

@dpsutton ignoring the contributor workflow reinforces my point.

Look, I have no problem if the core team doesn’t want contributions from the community - I just think it would be beneficial for everyone if that policy was stated explicitly and unambiguously. After all, there’s clearly something missing if, as you say, “They have been through this argument many times.” and it keeps resurfacing.

1 Like

I’m not sure what you mean by ignoring the contributor workflow. They have listened and talked about it ad nauseum. “Building on the previous point about optics, uncharitable observers might interpret this as a deliberate choice by the core team to make it difficult to submit contributions,” you seem to be taking what you called an “uncharitable” view of their motivations. It is not to suppress or inhibit or prevent your contributions. it is only to keep things in order. There are strong arguments for patches that they have been through as well.

They listened to the arguments to move to PRs but they were unswayed by them. They did not ignore the arguments.

2 Likes

I mean the workflow contributors use to prepare changes to the code, submit those changes for review, and update the changes if requested. I think a majority of contributors would favour pull requests over the legacy “create a patch file and attach to a JIRA” model, and both models provide much the same ability “to keep things in order”.

More generally, balancing contributor workflow preferences with the preferences of the core team is one aspect of a robust community management function. And my concerns around this aren’t just technical in nature - there’s a whole governance piece that seems undercooked.

At a minimum, the mere fact that these kinds of discussions keep rearing their heads every so often (for at least the 6 years since I first starting using Clojure) is a bit telling. Sweeping it under the carpet by saying things like “we’ve had this conversation before” and implying that it shouldn’t be raised again, is counterproductive. The evidence is that whatever had previously been decided is not meeting the community’s expectations, and either those expectations need to be more firmly managed (e.g. as I suggested in my previous reply), or the core team needs to take the community’s feedback a little more seriously and respond to it in some way. These are both reasonable outcomes, unlike the status quo.

@pmonks It hasn’t been swept under the carpet at all. Please read this email thread, from 2012, including Rich Hickey’s reponse: https://groups.google.com/forum/#!msg/clojure/jWMaop_eVaQ/3M4gddaXDZoJ

How much more “over the carpet” could he be?

@andy.fingerhut the issue of ease of contribution to core keeps coming up, and each time the response is along the lines of “this has already been decided and will not be revisited, so please stop discussing it.”. That’s pretty textbook carpet sweeping, no?

I also find it intriguing that everyone thus far on this thread has myopically focused on the point about the technical contribution process, while ignoring the point about governance (which I happen to think is the more important of the two).

You asked for why the patch submission process is the way it is (and you have asked other questions – I know). You have been given an answer for the first part of it, from the owner of the project. That isn’t sweeping it under the carpet, it is answering your question. Discuss it all you want, but if the owner of a project has heard about lots of different ways it might be done, and made their decision, unless you actually have new information they were not aware of before, do you have any reason to expect their answer to change?

Do you expect to force them to change their practices against their will? That isn’t exactly a good way to motivate them to adopt a different way of doing things.

Analogy: The community doesn’t like the way you choose the food you eat. We want to come up with a common ground on your choices for what you eat, vs. the community’s choices for what you eat. Will you agree to their decisions?

If I have been myopic in the topic, it is simply because I am answering the question that you have that I best know the answer to.

@andy.fingerhut different community members continue raising this as a pain point in different forums and at different times. @orestis’ post is merely the latest example.

While the core team is absolutely within its rights to ignore that feedback in favour of their own preferences, doing so says a lot (perhaps unintentionally) about their desire for and interest in input from the community.

[edit] I feel like I’m starting to repeat myself, so I’m not going to respond further on this particular topic. If anyone wishes to discuss governance, I’d be more than happy to jump back in.

Your words misrepresent the situation. They are not “ignoring” the feedback. They have heard it. Over and over again from many different people. They made a decision that included that feedback.

1 Like

My name was mentioned, but my intentions were misunderstood. I am saying: I want to help, other people want to help. How does the core team wants us to help? Are there things that are currently the bottleneck for them that we can help remove?

I am not saying: I would contribute but the current process turned me away. I am not questioning the current process because it has been discussed in the past and conclusions have been reached.

I am saying: Hey, here’s how other communities are doing things, is the core team interested in that?

In my world, they are the ones spending all their time on this and will bear the ultimate responsibility, whereas I, even with all my good intentions, will only spend a tiny fraction of my time because I have a day job. So I ask them: can I help directly with that tiny fraction? It’s ok for them to say no, so I’ll go back and answer beginner questions in Slack. That might be much more effective in the end for everyone involved.