-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Simplify [T; N]::try_map
signature
#126249
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
Simplify [T; N]::try_map
signature
#126249
Conversation
d09382e
to
1193cef
Compare
library/core/src/array/mod.rs
Outdated
pub fn try_map<R>( | ||
self, | ||
f: impl FnMut(T) -> R, | ||
) -> <R::Residual as Residual<[R::Output; N]>>::TryType |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still-pretty-noisy signature cannot reuse ChangeOutputType
without falling afoul of either the type_alias_bounds
lint or having an even more grody <<T as Try>::Residual as Residual<blahblahblah>>::TryType
.
One option that we do have that requires slightly more implementation work (changing the internals of the ones that use NeverShortCircuit, mostly) is this:
#[unstable(feature = "array_try_map", issue = "79711")]
pub fn try_map<R>(
self,
f: impl FnMut(T) -> R,
) -> impl Try<Output = [R::Output; N], Residual = R::Residual>
where
R: Try<Residual: Residual<[R::Output; N]>>,
Even further alternates might exist, but I think most of them involve sitting down for a good while and thinking very hard about how the traits relate to each other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning impl Try
isn't acceptable, IMHO, because it means that things like a.try_map(…).unwrap_or(…)
don't work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
basically agreed, which is what makes me annoyed the type_alias_bounds
lint fires on changing the type ChangeOutputType
alias to match. like, that can't possibly be right, can it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I'm reciting this issue: #125709
library/core/src/array/mod.rs
Outdated
pub fn try_map<F, R>(self, f: F) -> ChangeOutputType<R, [R::Output; N]> | ||
pub fn try_map<R>( | ||
self, | ||
f: impl FnMut(T) -> R, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have a libs-api policy for using in APITs given the fact that the synthetic type param they get lowered to can't be specified and the fact that the majority of stdlib fns that take Fn*
s use an explicit param for historical reasons?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The closure can be given type annotations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, but if one for whatever reason would like to force the closure to be non-capturing for example (quite an artificial one I know), the user can't do so via try_map::<_, fn(_) -> _>
but needs to do (|…| …) as fn(_) -> _
. I'm not talking about practical application here, I'm just curious about T-libs-api's stance on the use of APITs vs. explicit type params in the stdlib going forward (a topic I'm pretty sure has been discussed in the past).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ehn. I think that thinking about it in terms of "APITs" instead of "can someone actually write the damn code?" is a very compiler-brained way to look at it, and that any policy established shouldn't apply equally to a hypothetical random trait versus the impl Fn*
traits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's my experience that unnecessary things being in a type signature makes it harder to work with them because now it has to be given as a parameter at every single site, forever and ever, when you actually just wanted to specify the type of R
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
T-libs-api's stance on the use of APITs vs. explicit type params in the stdlib going forward (a topic I'm pretty sure has been discussed in the past).
anyways, if T-libs-api has a policy on this, it would be news to me, and they should write it down in, er, the policy section of https://std-dev-guide.rust-lang.org
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fmease Part of the reason for stabilizing turbofishing of generics on things with APITs was the flexibility that gives to libs-api. Things like rust-lang/libs-team#362 where not being able to turbofish something -- and then not forcing people to add _
s -- gives nice flexibility for things.
TBH I find it extremely rare that there's a reason to turbofish an I: Iterator
or F: Fn
, and much prefer it being an APIT. I wish that https://doc.rust-lang.org/std/array/fn.from_fn.html had been impl FnMut
instead, because from_fn::<u8, N, _>(…)
is much worse than if it had been from_fn::<u8, N>(…)
.
But I don't think there's enough examples to make a libs-api pattern just yet.
1193cef
to
d695544
Compare
People keep making fun of this signature for being so gnarly. Associated type bounds lend it a much simpler scribbling. ChangeOutputType can also come along for the ride.
Redistributed some of the diff to |
Cool; I like where this ended up. It does change the signature, but it's an unstable method so any issues with that can be dealt with when (if) it comes up for stabilization. Want to do |
People keep making fun of this signature for being so gnarly.
Associated type bounds admit a much simpler scribbling.
r? @scottmcm