Comments (17)
I just stumbled across this post and may actually have the answers available because of another project. Here are the top 50 trait names ranked by average number of explicit mentions in the the top ~1000 Rust projects on GitHub as of November 2022:
Trait Name | Avg. Mentions per Project | |
---|---|---|
1 | From | 30.6213 |
2 | Display | 18.4828 |
3 | Default | 17.368 |
4 | Debug | 15.9195 |
5 | Send | 5.63669 |
6 | Iterator | 5.58225 |
7 | Clone | 5.37988 |
8 | Drop | 4.52071 |
9 | PartialEq | 4.39408 |
10 | Error | 4.35266 |
11 | AsRef | 3.96686 |
12 | Sync | 3.55503 |
13 | TryFrom | 3.52899 |
14 | Deref | 2.91006 |
15 | Fn | 2.65917 |
16 | IntoIterator | 2.59408 |
17 | Into | 2.33018 |
18 | FromStr | 2.1787 |
19 | Eq | 2.15621 |
20 | Serialize | 2.11243 |
21 | Future | 1.7645 |
22 | Hash | 1.72071 |
23 | PartialOrd | 1.58225 |
24 | FnMut | 1.57988 |
25 | Write | 1.5432 |
26 | Deserialize | 1.52899 |
27 | Copy | 1.40355 |
28 | FnOnce | 1.3716 |
29 | Ord | 1.20592 |
30 | DerefMut | 1.17633 |
31 | Stream | 1.12071 |
32 | Parse | 0.942012 |
33 | Add | 0.926627 |
34 | Unpin | 0.822485 |
35 | Index | 0.790533 |
36 | Read | 0.76568 |
37 | ExactSizeIterator | 0.757396 |
38 | Visitor | 0.753846 |
39 | Encode | 0.659172 |
40 | Sealed | 0.63787 |
41 | Sub | 0.63432 |
42 | Deserializer | 0.598817 |
43 | Sized | 0.589349 |
44 | AsyncRead | 0.583432 |
45 | Mul | 0.571598 |
46 | FromIterator | 0.569231 |
47 | ToTokens | 0.564497 |
48 | AsyncWrite | 0.551479 |
49 | Arbitrary | 0.531361 |
50 | Service | 0.478107 |
Based on this, Display
and Debug
should really be in the prelude.Error
is also pretty far up the list. But Future
is on the cusp, just behind serde's Serialize
trait (obviously not in the prelude) but ahead of some prelude traits like Ord
, PartialOrd
, FnMut
, and Copy
.
We can also do an over-time comparison between Future
and other similar traits, such as Iterator
. For a while it looked as if people would soon be mentioning the Future
trait almost as much as Iterator
, but the gap has widened since async/await was stabilized:
But looking at only projects with at least one usage of either, we can see that projects which write out Future
at all tended to write it out a lot, almost more so than a project which similarly mentions the Iterator trait:
This obviously doesn't compare usage of the respective Iterator::*
and Future::*
methods when the traits themselves are unnamed (doing trait resolution was well beyond the project scope), but these plots do support the idea that pub use Future
should be in the prelude as much as pub use Iterator
if not as much as pub use Iterator as _
.
We can also break down these mentions of the Future
trait by their position in the syntax, to see that people are writing manual impl Future for T
impls surprisingly often. The fn() -> impl/dyn Future
was on the rise until async/await, then was largely replaced. On the other hand, use of f(_: impl/dyn Future)
has been steadily increasing:
Compare this to the Iterator
trait, where impl Iterator for T
mentions dominate to a greater extent, and where the relative growth of the different syntaxes has remained fairly proportional after the -> impl Iterator
syntax was stabilized:
We can also investigate why people still type out fn() -> impl Future
at all, when async is available. It is about half as popular as before the async syntax was stabilized. But notice that people customize the lifetimes on returned futures just as much as before:
My take from this is that having Future in the prelude would be nice for a lot of projects even if async/await has reduced that need somewhat. However, other traits might be more important to add.
from wg-async.
Yeah, we should talk to the libs team about criteria. Personally, I think we probably don't want to add anything - I reckon a minority of programs involves async code at all and a small minority of those write impl Future
or implement a future because most just use async and await. Furthermore, those that do use explicit futures tend to just use them in a few places rather than everywhere, so importing them manually doesn't seem onerous. I think this all applies even more strongly to IntoFuture (aiui, the most common usage is implicitly in await
where it doesn't need to be imported at all)
from wg-async.
I'm currently thinking we should put the following traits forward for inclusion in the 2024 prelude:
Future
IntoFuture
This would mirror what we're including with Iterator
/ IntoIterator
, and would hopefully be fairly uncontroversial. @rust-lang/wg-async WDYT?
from wg-async.
A lot of code imports
futures::Future
. Would puttingFuture
in the prelude break this code?
I don't believe so. They both point to the same trait, so with the way imports work this would Just Work I believe: playground.
from wg-async.
-
Since
task::{Context, Poll}
is also needed to implementFuture
, includingFuture
in the prelude would be of little use from the standpoint of eliminating import effort during manual implementation. (This also applies toDisplay
andDebug
mentioned by @samsartor, which need other items in the fmt module for implementation.) -
The data provided by @yoshuawuyts does not appear to be very reliable, as we can see cases from the first page that clearly match irrelevant items (e.g., "S: futures::Stream" is considered to contain one ": Future", or "use futures::future::FutureExt;" is considered to contain three "Future"'s.). It should also be noted that the GitHhub search also searches forks by default.
-
If other async-related traits are added to the std (e.g.,
Stream
/AsyncIterator
), do we want to include them in the prelude as well?- If yes, should we repeat the same discussion in 3 years, or include it in prelude at stabilization?
- If no, why is
Future
trait special and the others are not?
-
Other traits that are not included in
std::prelude
but are widely used arestd::io
traits, which have module-level prelude (std::io::prelude
). The "only io-related code needs it" nature of io traits is somewhat similar to async-related traits, where "only async-related code needs it". Maybe we may want to consider the idea regarding module-level prelude (something likestd::future::prelude::{Future, AsyncIterator}
).
from wg-async.
If other async-related traits are added to the std (e.g.,
Stream
/AsyncIterator
), do we want to include them in the prelude as well?
- If yes, should we repeat the same discussion in 3 years, or include it in prelude at stabilization?
- If no, why is
Future
trait special and the others are not?
As far as I know the prelude isn't expanded in between editions, so yeah I think we should talk about whether there are things that would make sense to put in the prelude every ~3 years. That seems like a pretty good cadence to have a conversation?
To maybe look at this from a different angle: Future
represents the reification of the async effect - which means that if we create a type using async {}
, the only way we can refer to it in the type system is by using the impl Future
notation (as both universal and existential). This is much the same as the "iteration" effect, which is reified as impl Iterator
. Because async {}
notation is globally available, it would make sense for impl Future
notation to match. The key property here is not being able to implement Future
, it's being able to name it.
from wg-async.
Seems reasonable to me. I'm regularly surprised that Future
isn't in the prelude.
A lot of code imports futures::Future
. Would putting Future
in the prelude break this code?
from wg-async.
Playing devil's advocate for a bit, are Future
and IntoFuture
traits that really need to be in the prelude? Most people don't implement Future
directly, and probably even fewer call poll
or into_future
directly, so maybe it's reasonable to leave these as an advanced feature that people implementing low level async code import but most programmers don't use?
Put another way, what capabilities do we enable by putting them in the prelude?
(edit: accidentally said standard library instead of prelude in the first sentence. It's fixed now)
from wg-async.
If not in the standard library, then where would they be?
from wg-async.
are Future and IntoFuture traits that really need to be in the standard library?
They certainly need to be in the standard library to support async
and await
desugaring.
Most people don't implement Future directly
Yeah, but I would assume more people using them as impl traits in return or arg position, like fn x() -> impl Future<Output = ..>
, fn x(x: impl Future<Output = ..>)
which would be helped by implementing
I can see how IntoFuture
probably doesn't need to be in the prelude (since most people are just .await
ing on things), and I guess I could see Future
also not being there.
from wg-async.
Oh sorry, I misspoke! I meant to ask whether we need Future
and IntoFuture
in the prelude, not the standard library. I'll edit my comment.
from wg-async.
Most people don't implement Future directly
Yeah, but I would assume more people using them as impl traits in return or arg position, like
fn x() -> impl Future<Output = ..>
,fn x(x: impl Future<Output = ..>)
which would be helped by implementing
That's a good point.
I wonder what the bar is for including things in the prelude is? I'd assume it's for things that essentially all Rust programs will use. Almost every program uses Option
and iterators, for example. There are still a sizeable number of programs that don't use async though and therefore don't need to use Future
at all.
from wg-async.
I reckon a minority of programs involves async code at all and a small minority of those write
impl Future
or implement a future because most just use async and await.
This is something we can validate by searching GitHub:
lang:rust /: Future/
: yields 40.000 matcheslang:rust /: Iterator/
: yields 80.000 matcheslang:rust /Future/
yields 700.000 matcheslang:rust /Iterator/
yields 400.000 matches
GitHub code search does have a few limitations. For one the search is not case-sensitive. And it also includes lines which are part of comments. But if we interpret this as a rough indicator rather than a precise measurement, it would seem that Future
is used about about half as often as iterator in bounds. And likely sees comparable usage elsewhere.
What I'm taking away from this is that the Future
trait is probably used often enough that it would be justified for inclusion in the stdlib prelude. The most conservative interpretation of this is that Future
is used about half as much as Iterator
, one of the most used traits in the stdlib. By-volume that is a lot; and it would seem to me as enough to justify its inclusion. IntoFuture
is most definitely used less than the other traits, but it's also only been part of stable Rust for months, not years like the other traits. At least to me it seems that if we're going to put up Future
for consideration, IntoFuture
should also just come with so it would continue mirroring the Iterator
/IntoIterator
trait set it was modeled after.
My goal with this comment was to specifically request input from the Async WG for which traits (or even types!) we may want to put forward for inclusion. Once we have a rough consensus among ourselves, I was planning to put it forward to the libs team as an ACP to formally clear the acceptance criteria with them.
from wg-async.
It's possible that once we have AsyncIterator
we may see Future
used a lot more too, depending on how the API shapes up.
from wg-async.
This is something we can validate by searching GitHub:
I get completely different numbers here and simply clicking these links gives me bogus results (e.g., results with "lang" and "rust" as the found text). I think that at least the repositories searched depends on the user. So I'm not sure these are reliable numbers. Given that GH search also counts forks as different repos, these are also going to be inaccurate that way too. I think a better count might be by downloading the source to the top 500 crates on crates.io and using grep? Or some similar exercise
from wg-async.
I get completely different numbers here and simply clicking these links gives me bogus results (e.g., results with "lang" and "rust" as the found text)
Oh it may be that you don't yet have access to the new code search feature. It's far more accurate than the previous search, and you can do things like lang:rust
to scope it just to files written in Rust, and apply regular expressions to look for specific occurrences.
from wg-async.
The 2024 prelude is now available behind a flag on nightly. We should consider PR'ing Future
and IntoFuture
to it.
from wg-async.
Related Issues (20)
- Stabilization: impl_trait_projections
- use GAT to redesign trait Stream HOT 3
- Reading club: Async iteration III
- Reading club: Writing a basic `async` debugger
- Open discussion 2023-10-26
- Reading Club: A Mechanism for Async Cancellation HOT 1
- Open discussion / goal planning: 2023-11-09 HOT 1
- Goal planning 2024: 2023-11-30
- Roadmap planning: 2023-12-07
- Roadmap planning: 2023-12-14
- Open discussion: 2024-01-11 HOT 2
- Roadmap planning: 2024-01-18
- Discuss `async Drop`
- Roadmap planning: 2024-01-25
- Discuss `impl Future` for thread `JoinHandle`
- Discuss `AsyncIterator` prototype
- Discuss async portability
- Design meeting: Auto concurrency
- Design meeting: Async cleanup
- Design meeting: Async drop
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from wg-async.