I think it’s definitely tough to strike the right balance here, and I’m personally somewhat wary that we can create a set of concrete guidelines which aren’t likely to change over time, but it’s certainly worth a shot! One rule of them I normally take is that once something is in the standard library, it must be supported until the end of time, so it should be worth it!
I believe one of the main charters of the standard library is to set the idioms and standards for the rest of the Rust ecosystem as much as possible (you alluded to this as well). For example traits like Iterator, Error, Read, Into, etc all belong in the standard library. These traits define an idiomatic and common interface to allow libraries to interoperate with one another. In terms of idioms, I also think the standard library’s APIs and what it exposes on core types like Vec and String are strong precedents for custom downstream APIs in terms of functionality exposed. Essentially, I definitely agree with (2) above, and I definitely don’t think it should be taken lightly.
One reason I might add to your list above is: if a feature is used ubiquitously throughout the ecosystem, it should be in the standard library. For example there’s really no need for TCP/UDP support to be in the standard library in the sense that the compiler and distribution do not depend on it. It’s such a core interface, however, and so ubiquitously used, that it should definitely be included. A rule of thumb here might be that if a dependency shows up in 90% of Cargo projects, then it’s a strong candidate for being in the standard library.
To comment on some other points you made:
My only reservation about this is that it’s often nice to write small one-off scripts, but Cargo does not currently support this very well. For example I can’t gist a playpen snippet which makes an HTTP request or parses JSON. Otherwise, though, I definitely agree that in general “having fewer dependencies” is not a great motivating factor for moving content into the standard library. There are some strong benefits from being used as a dependency:
- Debuggability is increased because Cargo can compile dependencies with debug information and unoptimized
- Iteration on design can happen much more quickly outside the standard library, especially adding new features
- Living outside the standard library means that multiple versions can exist in an application. For example if large breaking changes want to be made to an API, it can be done without breaking other downstream code as you’ll just include both versions.
I agree that the rust-lang organization is a prime location for “curated crates”, but it will take some time to get here. I am not personally proud of the API exposed by the time crate today, for example, and reworking some of the existing crates we have will take time. Overall, though, I expect this to become a good place for high-quality libraries to live.