-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Tracking Issue for Result::into_ok_or_err
/ feature(result_into_ok_or_err)
#82223
Comments
I don't feel that strongly, but considered this (it was suggested to me when implementing the PR) and didn't do it because it can be achieved using The same is true for a hypothetical |
I would narrow down the names to ones that are |
The API surface of Result/Option is quite large already. The bar for adding even more methods for them should be raised because it's getting harder for me to remember and use all of them. |
There are multiple cases in the stdlib (e.g. ignoring external crates) where something like this is beneficial. The alternatives are less clear ( There were also multiple PRs proposing this, showing it's not just me that considers it to meet the bar for addition. I also think that broadly the current design of these types (and many other APIs in libcore, Iterator as an example, or the functions on the numeric types) favor functionality over minimalism in the API, but that's more of a philosophical question. You also don't have to use them if you fail to remember them. |
Please don't say this, it's a fallacy :-) |
This method became more relevant since deprecating |
Yeah, that actually motivated this. Edit: FWIW in the mean time I think |
With let (Ok(x) | Err(x)) = slice.binary_search(&42); The method this issue tracks could still be useful for chaining, but I thought I may as well mention the above ^^ |
Calling it |
It will be more useful if we can impl it for |
I think it's best to keep this method symmetric. It's not always clear that E should be converted to T rather than the other way around. |
@rfcbot merge This is impl<T> Result<T, T> {
pub const fn into_ok_or_err(self) -> T;
} There are a lot of possible names for this function, but I think |
Team member @m-ou-se has proposed to merge this. The next step is review by the rest of the tagged team members: Concerns:
Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
I think the name here being a bit verbose is fine, because it's really only for slightly-weird situations, as normally one would have an error as E and a non-error as T, in which case this is method doesn't apply. Thus a slightly-longer name to help emphasize it's in the unusual T == E case makes sense. |
Of the above comments, I think my perspective most closely matches #82223 (comment) and #82223 (comment). The bar for whether a method goes on
So we're starting with a niche set of methods (a few percent of crates ever encounter a Result<T, T>), and a fraction of the call sites of those methods, and not really offering a substantial improvement to even those. From the perspective of looking at how ubiquitously a transformation is needed and how much giving it a name can facilitate understandability of the code, I would prefer
This is not a convincing justification for @rfcbot concern rather not |
I agree with @dtolnay on this one, though I think the second comment he linked is the much more persuasive justification for me. The fact that we already have stable or-patterns that let you write almost the exact same thing, and which is useful in far more situations makes me strongly prefer we focus on pushing users towards using or-patterns rather than stabilizing this API. In general I prefer a smaller API surface area with more expressive and composable features to one with many useful helper methods, since it's much easier to remember a smaller set of features. The only difference I can see between this API and or-patterns is that this API can be used in the expression position, but or-patterns are exclusively used in let statements or match expressions and require an extra subsequent expression to refer to the bound variable. This will probably be pretty annoying if you're forced to break up a long chain of method calls but I would prefer to resolve this by finding a small additional language syntax (some sort of postfix match expressions maybe? As a follow up though I imagine that many users don't know about or-patterns, so I would love to see a PR where we add some additional docs to the relevant APIs in For binary search it looks like we already have a relevant example which we could update. let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let num = 42;
let (Ok(idx) | Err(idx) = s.binary_search(&num);
s.insert(idx, num);
assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]); |
Interesting, I was expecting that number to be higher. We should also check out |
(I should also note that |
Recently, I've read the interface design rules in the "Rust for Rustaceans" book and it mentions "The Principle of Least Surprise". Personally, I dislike using let pattern for that - it looks noisy and less clear. Btw. @m-ou-se thanks for mentioning partition_point, it's indeed more meaningful for this usecase! |
I went ahead and submitted a PR to update the docs for |
…r=Mark-Simulacrum Update binary_search example to instead redirect to partition_point Inspired by discussion in the tracking issue for `Result::into_ok_or_err`: rust-lang#82223 (comment) People are surprised by us not providing a `Result<T, T> -> T` conversion, and the main culprit for this confusion seems to be the `binary_search` API. We should instead redirect people to the equivalent API that implicitly does that `Result<T, T> -> T` conversion internally which should obviate the need for the `into_ok_or_err` function and give us time to work towards a more general solution that applies to all enums rather than just `Result` such as making or_patterns usable for situations like this via postfix `match`. I choose to duplicate the example rather than simply moving it from `binary_search` to partition point because most of the confusion seems to arise when people are looking at `binary_search`. It makes sense to me to have the example presented immediately rather than requiring people to click through to even realize there is an example. If I had to put it in only one place I'd leave it in `binary_search` and remove it from `partition_point` but it seems pretty obviously relevant to `partition_point` so I figured the best option would be to duplicate it.
…r=Mark-Simulacrum Update binary_search example to instead redirect to partition_point Inspired by discussion in the tracking issue for `Result::into_ok_or_err`: rust-lang#82223 (comment) People are surprised by us not providing a `Result<T, T> -> T` conversion, and the main culprit for this confusion seems to be the `binary_search` API. We should instead redirect people to the equivalent API that implicitly does that `Result<T, T> -> T` conversion internally which should obviate the need for the `into_ok_or_err` function and give us time to work towards a more general solution that applies to all enums rather than just `Result` such as making or_patterns usable for situations like this via postfix `match`. I choose to duplicate the example rather than simply moving it from `binary_search` to partition point because most of the confusion seems to arise when people are looking at `binary_search`. It makes sense to me to have the example presented immediately rather than requiring people to click through to even realize there is an example. If I had to put it in only one place I'd leave it in `binary_search` and remove it from `partition_point` but it seems pretty obviously relevant to `partition_point` so I figured the best option would be to duplicate it.
@jplatte I also think we need a I also believe such feature on Result is error prone for user, the need to be very explicit on the name show it. |
I wanted to get a reader on an RrLock and also put a type on the binding so that it was clear what was going on, to do that using or-patterns you have to write... this entire thing: let db: &RwLockHashSetStaticStr = get_str_db_rw_lock_ref();
let (Ok(read_guard) | Err(read_guard)): Result<
RwLockReadGuard<_>,
RwLockReadGuard<_>,
> = db.read().map_err(|e| e.into_inner()); So I don't really think that or-patterns are as good a solution as having a method, because to make them work nicely you end up being nearly forced to not write down as many types in the code. |
@Lokathor if I understand correctly, you want to write this? let read_guard: RwLockReadGuard<_> =
db.read().map_err(|e| e.into_inner()).into_ok_or_err(); I think let read_guard: RwLockReadGuard<_> =
db.read().unwrap_or_else(PoisonError::into_inner); |
@rfcbot fcp close Nothing compelling has been brought forth since then. I would like to remove this method. That's right; I don't understand how this would possibly be controversial. |
Team member @dtolnay has proposed to close this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
|
👍 to close. To be useful, this needs either an And @Stargateur's comment above (#82223 (comment)) reinforces that for me. The problem here is not the isomorphic structure of the enum, but the semantic meaning of the variants here. A method like this is totally fine on |
This is certainly not the place to have that extended discussion, which I think you already know, so I don't know why you brought it up. |
I agree we should close this. We have very few cases where we use a For The equivalent of the now deprecated There are not many usages of Similar for |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
Remove unstable Result::into_ok_or_err Pending FCP: rust-lang#82223 (comment) `@rustbot` label +waiting-on-fcp
The final comment period, with a disposition to close, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. |
Remove unstable Result::into_ok_or_err Pending FCP: rust-lang#82223 (comment) ``@rustbot`` label +waiting-on-fcp
Remove unstable Result::into_ok_or_err Pending FCP: rust-lang#82223 (comment) ```@rustbot``` label +waiting-on-fcp
Remove unstable Result::into_ok_or_err Pending FCP: rust-lang/rust#82223 (comment) ```@rustbot``` label +waiting-on-fcp
FCP is now complete and #100604 has been merged, closing. |
…mulacrum Update binary_search example to instead redirect to partition_point Inspired by discussion in the tracking issue for `Result::into_ok_or_err`: rust-lang/rust#82223 (comment) People are surprised by us not providing a `Result<T, T> -> T` conversion, and the main culprit for this confusion seems to be the `binary_search` API. We should instead redirect people to the equivalent API that implicitly does that `Result<T, T> -> T` conversion internally which should obviate the need for the `into_ok_or_err` function and give us time to work towards a more general solution that applies to all enums rather than just `Result` such as making or_patterns usable for situations like this via postfix `match`. I choose to duplicate the example rather than simply moving it from `binary_search` to partition point because most of the confusion seems to arise when people are looking at `binary_search`. It makes sense to me to have the example presented immediately rather than requiring people to click through to even realize there is an example. If I had to put it in only one place I'd leave it in `binary_search` and remove it from `partition_point` but it seems pretty obviously relevant to `partition_point` so I figured the best option would be to duplicate it.
Remove unstable Result::into_ok_or_err Pending FCP: rust-lang/rust#82223 (comment) ```@rustbot``` label +waiting-on-fcp
Btw, if you find yourself in a need for such code, you can write this: |
For those who want the method syntax, an extension trait can be used: pub trait ResultExt<T> {
fn into_inner(self) -> T;
}
impl<T> ResultExt<T> for Result<T, T> {
fn into_inner(self) -> T {
let (Ok(i) | Err(i)) = self;
i
}
} |
Feature gate:
#![feature(result_into_ok_or_err)]
This is a tracking issue for
Result::into_ok_or_err
, a method to get theT
out ofResult<T, T>
regardless of which variant is active.Public API
Steps / History
Result::into_ok_or_err
method to extract aT
fromResult<T, T>
#80572Unresolved Questions
What color should the bikeshed beWhat name should it have?Some options that have been suggested:
Result::into_ok_or_err
Result::ok_or_err
Result::into_either
Result::into_inner
Result::either_value
Result::unwrap_either
Result::
{value
,into_value
} #79315 proposed?The text was updated successfully, but these errors were encountered: