Impl Not for Result

It seems clear that implementing Not doesn't really fit. Is there any opposition to a flip method?

impl<T, E> Result<T, E> {
    fn flip(self) -> Result<E, T> {
        match self {
            Ok(t) => Err(t),
            Err(e) => Ok(e),
        }
    }
}
3 Likes

I think mostly from a philosophical point of view. Where having this sort of method seems like you are abusing result to be a generic ether type.

19 Likes

I think this equivalent to result.err().ok_or(HelpfulError)? This little detour through Option for such a niche case seems reasonable.

Well, there might be cases where you want an error to happen. That's the reason why unwrap_err exists.

unwrap_err panics if the Result is Ok, but there is no function that returns an error if the Result is Ok.

1 Like

If we never had Result in the language it'd be possible to experiment with API design for it. Too bad trait impls are insta-stable because we feel like this is something that would heavily benefit from experimentation.

At least parsers would be able to take benefit from it.

That isn't what is being asked for here though. That could very well be added behind a feature gate. Or even a new topic. Though I think Inline error recovery - #16 by steffahn is basically what is being asked for here anyway.

You could already experiment with this today, in multiple ways. The most obvious would be to add a method (e.g. .flip()) yourself, via an extension trait. You could then make an argument for why that method is not only useful but so incredibly useful it needs to have a one-character unary operator (as well as whether it fits the semantics of that operator). As a hint, such an argument would start with "a massive number of crates are using this, or contain a code pattern that would benefit from this"; that's the threshold such a proposal would need to meet, at a minimum.

You could also experiment with the syntax you propose using a macro, or a different Result type, and then use that to make a similarly compelling argument.

We almost never jump directly to "this needs short native syntax". Important steps that come before that: "does this need any native syntax", "could this be done in a library", "could this be done in a macro", "what's the most idiomatic way to write this today", "should this be done at all".

22 Likes

Yeah, Option::filter existed for almost two years as a third-party library before it was stabilized in std. If you think a Result::flip is useful, then you can do the same thing.

2 Likes

But names like "flip" and "reverse" are confusing whereas the operator would be less confusing due to not having a "name" exactly.

@Soni Two library team members (myself included) have already gone on record to say what would be minimally required to make this proposal actionable. I would suggest focusing your efforts on that. Otherwise, this discussion is just chasing our tails around the maypole.

11 Likes

Maybe it's because I came from a background of languages with confusing operators, but personally I would find an operator much more confusing than a named method.

I'd also probably agree that the use cases put forward so far would probably be better served by you defining your own Either type, and then you can do whatever you want.

13 Likes

@bascule, would you perhaps tell us what those languages were and - should you feel like - share a horror story or two about operators? :slight_smile: Might be quite interesting

Perl and Ruby.

Especially the former would devolve into indecipherable line noise.

Aww, I do have a soft spot for the "Perl Periodic Table of the Operators"! :smiley:

On the flip side, after having coded in Python for far too long, I'd read ! in front of a Result as "not truthy" - i.e., equivalent to is_err(). Before reading this thread I wouldn't even have thought of it flipping the branches.

7 Likes

yeah !0 trips ppl up too...

2 Likes

First of all, that's about the most useless response you could have had. But realistically? Just about every language considers negation of an integer to mean bitwise negation.

Please be constructive. Posting responses like that is inconsiderate and rude.

Other languages I've seen have a separate operator for bitwise negation, javascript/C/C++ use ~.

I think Rust doesn't use ~ because it used to be the operator to construct a Box originally, and prefix ~ is also how it was written as a type.

6 Likes

C and C++ have implicit conversions, and C's logical operators also have the type int, as _Bool didn't exist until C99. So it's not really possible to use the same operator for logical and bitwise "not".

With Rust's explicit conversions, there's a firm distinction between Not for bool vs. other types.

3 Likes

Since it's April 1st... If you like truthiness, you might like my eh crate, read like a Canadian "eh?" There's also the truthy crate that looks a little more serious.

4 Likes

There's also the either crate providing a generalized form of Result that's not tied to error handling.

One way to justify a new method on Result would be to demonstrate that there are lots of uses of Either that ought to be Result, but that really benefit from the flip method it provides. either also provides From and Into for Result so that you can convert between the two sum types trivially.

5 Likes