In this post I'd like to explore the quality libraries aspect of the Rust 2018 roadmap RFC. I'll lay out the framework that underpins my perspective on open source development as a starting point for conversation.
Quality means dependability. It also means a bunch of other things, but I'd like to focus on dependability here. The roadmap discusses sharpening Rust's offerings in a few focus domains, and I think a key to doing that is by supporting the dependability of libraries that fit within them.
What exactly is dependability though? I think a dependable library consists of:
- Dependable API
- Dependable examples
- Dependable documentation
- Dependable maintainership
A quality library has a dependable API that's idiomatic and consistent.
We have the API Guidelines which lay out what idiomatic Rust looks like, and some of the hard-learned lessons of maintaining a stable Rust API. I think we've got a pretty good handle on this point going forward, so I won't spend a lot of time on it.
A quality library has a range of examples demonstrating concepts ranging from introductory to advanced usage.
We have the Cookbook which provides a common framework for examples that are consistently presented and easy to consume. This is another point I think we've got a good handle on so will skip over it too.
A quality library has extensive documentation that is discoverable, motivating and instructive.
Compared to some other languages, Rust already has great tools for writing documentation and they're getting even better. Writing documentation is a really deep skill though, and it can feel like a chore to keep the docs moving while an API is still churning. It can also feel like an afterthought because docs don't technically need to exist before a library can be used. It's my belief though that more quality docs results in fewer issues, so we should give them more attention.
I think we should produce some resources on what really helpful documentation looks like and help stable libraries polish up their public presence. They should be just as first-class as the API itself.
A quality library has appropriate maintainership. I say appropriate because I think maintainership is the most personal and least measurable of these points. It's also never done. Over their lifetime, libraries might pass through multiple maintainers, multiple times. It affects every library author in every language to varying degrees. So we should all talk about it.
I think there's a key factor that underpins dependable maintainership that the Rust community has already been fostering for a long time: a willingness to collaborate. I'll dig into that more later.
Supporting producers and consumers
ergo are important for library consumers (the people building applications) to be productive. Maybe they'll also help shift some of the maintenance burden closer to the consumers' domain.
There's no single solution to supporting dependable maintainership that's going to fit everyone. Once the willingness to collaborate is established, the rest really depends on context.
People write libraries for all sorts of reasons. And they have all sorts of goals in mind for them. I'm going to assume we're talking about libraries that producers want to be consumed.
First, let's set the priorities. Consumers depend on producers. Without producers, consumers have a lot more work to do. You could suggest that producers depend on consumers because there's no fun in producing something that nobody is going to consume. There's definitely some truth to that, but the flow of value is skewed far more towards consumers. They get software. Producers typically get goodwill, sometimes not even that.
A big problem is many libraries are maintained by a fraction of a single person (where that person is possibly spreading their fractions across many other libraries). When many people then depend on that library, that's a lot of pressure for a single fraction of a person to keep up with.
The single best thing we can do for maintainers is share the burden. A single fraction of multiple people maintaining a library is better than a bigger fraction of a single person. We should support library maintainers sharing the burden of maintenance. Our tools have come a long way in supporting a more social development model, but there is a catch.
Maintainership without ownership is unsustainable. What I mean is expecting people to keep the lights on without allowing them to exercise ownership over a library isn't going to keep people interested for long. So when we share the burden, we need to also share the ownership. That's actually pretty hard to do.
To sum it up, I think we should support producers by supporting socially sustainable development, whatever form that takes for a particular library.
The biggest way we can support consumers is by supporting the producers of libraries they want to consume. Building unified, domain-specific projects collecting multiple libraries together will also help people be more productive when working in that domain. Maybe they'll also push the burden of maintenance for dependencies of those domain-specific projects closer to the domain itself, and reduce friction in support.
Tools, resources, results
I've laid out my thinking around what makes a dependable dependency. So how should we go about producing and supporting them? I think we should work towards three interdependent outcomes for each point raised above:
- Tools to help support dependability. Things like the
- Resources to help realise dependability. Things like the API Guidelines, Cookbook and a guide on producing great documentation.
- Dependable dependencies. We should actually have stable, dependable libraries.
What do you think?
These are my thoughts, I'd like to work through them in more detail over time, but I really want to know what you think! There are certainly people who've been thinking about these problems for longer than I have. I've called out collaboration as the key to the most important aspect of dependable dependencies: maintainership. So let's collaborate and see what light other perspectives shed on the problem.