Skip to content

Add document on criteria for inclusion in std #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
---

- [Code considerations](./code-considerations/summary.md)
- [Criteria for inclusion in `std`](./code-considerations/criteria-for-inclusion.md)
- [Design](./code-considerations/design/summary.md)
- [Public APIs](./code-considerations/design/public-apis.md)
- [When to add `#[must_use]`](./code-considerations/design/must-use.md)
Expand All @@ -48,8 +49,8 @@
- [Documentation](./documentation/summary.md)
- [doc alias policy](./documentation/doc-alias-policy.md)
- [safety comments policy](./documentation/safety-comments.md)
- [how to write documentation](./how-to-write-documentation.md)
- [reviewing doc changes](./reviewing-doc-changes.md)
- [how to write documentation](./documentation/how-to-write-documentation.md)
- [reviewing doc changes](./documentation/reviewing-doc-changes.md)

---

Expand Down
70 changes: 70 additions & 0 deletions src/code-considerations/criteria-for-inclusion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Criteria for inclusion in `std`

**Note**: *The process for deciding what does and does not get added to the standard
library is too complex to reduce to a set of concrete rules. Ultimately we rely
upon the expertise of members of the library API team, but here we attempt to
document the reasoning that has been used historically to guide contributors
and team members and to ensure long term consistency in how these decisions are
made even as the team membership naturally changes over time.*

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it is worth an upfront disclaimer that policies have changed over time and that we probably wouldn't add some things to std now which got added back in the day? (And we might learn things which mean that things which got rejected in the past might be reconsidered)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid. In particular, "The inclusion of any particular API in the standard library in the past should not be taken as precedent for future such APIs."

## Reasons For Inclusion

* APIs where there is a clear best implementation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add "General purpose APIs likely to be useful to many users" or similar text. E.g., one could imagine an API which ticks all these boxes, but if it is only useful for games programmers then we probably don't want it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that would depend on circumstances; we may be willing to add APIs exclusively useful to a subset of users. For instance, portable SIMD, or miscellaneous OS-specific APIs. And there are probably fewer people using those than there are game programmers.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe "many kinds of users" rather than "many users"? Like SIMD feels more generally useful than say OpenGL support, even if the latter might have more users.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nrc I think we'd rule out OpenGL support for several other different reasons. Among them: it's a substantial and disproportionate maintenance burden, it's likely to become outdated (it already is given Vulkan), it's likely to have massive portability hazards, and it isn't something where there's an "obviously best" implementation as opposed to various opinionated choices.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe OpenGL is a bad example here. Maybe something specialised like text layout or something? I'm sure there are crates which would be better be kept as crates simply because they're unlikely to be used by a broad slice of users?

Put it another way, I agree with you that it "would depend on circumstances" but it seems we want some guideline about APIs being general purpose as a starting point.

* APIs where there is a strong benefit to having only one, such as common
traits (e.g. `Error`, the `Fail` trait from `failure` crate showed the cost
of competing error traits and how it causes ecosystem fractures)
* Core value propositions: APIs that we want to use in examples for our
learning materials to demonstrate rust's core value propositions. (e.g.
scoped threads simplifying examples demonstrating thread and memory safety)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't quite describe it, but I think there is an extension to this principal that we want programmers to be able to 'get started' with just std, which is why we have formatting stuff and println in std, even though they don't tick other boxes here.

Copy link
Member

@the8472 the8472 Aug 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have an argument parsing library, terminal prompting (there have been proposals with somewhat mixed reception I think), regular expressions, http, json or other stuff that would sure be convenient in toy programs.
We don't include a repl either.

The stuff for examples allows the example code to take inputs and make outputs instead of existing in a never-called vacuum.

Perhaps if you mean "hasn't even had a high school programming course before and wants to explore CS101 basics" then it might work. If "getting started" means translating a 20-lines-of-python problem to rust for the first time then it doesn't work.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm definitely thinking more of 'hello world' than a practical program, or like the examples from the Book or similar tutorials

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is already covered by "want to use in examples" then? Just to have those examples print something we need IO. And "at least as powerful as brainfuck" is table stakes anyway.

Write, stdout() and Display are covered by

APIs where there is a strong benefit to having only one

So most of that already falls out of the given reasons.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's ok if there is some overlap here? Like, I certainly think it is a reasonable objective that a new programmer can sit down and write a few first programs without needing deps. We can certainly argue about what that means (I would like terminal prompting/basic parsing to be in std, for example, and I don't think that extends to regex/http/json, but I think that it is reasonable to have different opinions here).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It still seems pretty very similar to writing documentation. E.g. if hypothetically println!() didn't exist and the rust book had to copy-paste some boilerplate to write to stdout in every example then they could open an issue and say hey, this would simplify our tutorial a lot if this function existed.

* Unsafe primitives: APIs that reduce the need of or centralize difficult to
implement unsafe code
* Portability: APIs that are not dependent upon any platform's abstractions or
features

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think another principal is something along the lines of we want to provide the foundational building blocks to support many programming paradigms rather than choose one paradigm for all users and make it first class in std. So atomics (and mutexes to a lesser degree) are provided not because we think they are the best paradigm for concurrency but because they are required to build any paradigm.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nrc I don't think that's quite an accurate description. We will, sometimes, choose a common paradigm and support it in std, just not necessarily to the exclusion of other paradigms.

We don't just support mutexes because they're useful for building other paradigms, we also support them because they're useful in their own right as a paradigm.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Historically, it has certainly been a guiding principal for how std was designed. For mutexes, I think that there is the locking paradigm there, but the interesting question is why choose that paradigm and not actors or message passing, etc.? And the answer is because it is easier to implement actors with mutexes than to implement mutexes with actors.

That philosophy may have changed recently and of course real life is more nuanced than this simple description, but I think it is a good principal and it's served us well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We did also provide message passing (though we're experiencing some regret there).

I think an underlying principle of "we're not looking to force users into one paradigm over another" is valid, but I do also think we'd happily add support for a specific paradigm that not everyone uses if it's popular and meets all the other criteria (e.g. not TMTOWTDI).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do also think we'd happily add support for a specific paradigm that not everyone uses if it's popular and meets all the other criteria (e.g. not TMTOWTDI).

I think this is worth discussing in some detail. IMO it begs the question why have one paradigm and not another? And it might open a slippery slope to having many paradigms in std, which seems very sub-optimal. IMO this comes back to the principal of there being only one good solution, but lifted from APIs to paradigms.

## Reasons Against Inclusion

* APIs where there are multiple legitimate alternatives with different tradeoffs
* APIs that are excessively complex or difficult to maintain (e.g. Needle api
or `rand` crate)
* API instability
* All new APIs will be subject to `std`'s perma 1.0 stability policy, so
certain classes of APIs that are more likely to require breaking changes
such as cryptography generally face a higher bar

## Reasons that may seem like criteria but aren't

* APIs that need access to the host operating system
* APIs that are in other languages' standard libraries
* APIs in crates with high download numbers

## Case Studies

### [`Mutex`](https://doc.rust-lang.org/stable/std/sync/struct.Mutex.html)

We would likely still add `Mutex` to `std` if it were proposed today.

#### For

- Core value proposition: mutex is one of the fundamental primitives for thread
safe interior mutability and is frequently used in examples.

#### Against

### [`mpsc`](https://doc.rust-lang.org/stable/std/sync/mpsc/index.html)

We likely would not add `mpsc` to `std` if it were proposed today.

#### For

* It helped demonstrate rust's core value proposition showing of rust's
"fearless concurrency" in examples and learning materials

#### Against

* There are many different legitimate alternative approaches with tradeoffs, it
is not a one size fits all solution.
* It's a complex API with multiple issues and has been a large maintenance burden.
* It's currently being replaced with a completely different implementation to
solve some of these maint issues ([93563](https://github.com/rust-lang/rust/pull/93563)).

### [`scoped threads`](https://doc.rust-lang.org/stable/std/thread/fn.scope.html)