Skip to content
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

Allow chaining of comparisons #2083

Open
Nokel81 opened this issue Jul 26, 2017 · 17 comments
Open

Allow chaining of comparisons #2083

Nokel81 opened this issue Jul 26, 2017 · 17 comments
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.

Comments

@Nokel81
Copy link
Contributor

Nokel81 commented Jul 26, 2017

Namely for all comparison operators they should be allowed to be chained. The easy way of disambiguating them is since they are all binary operators just chain them with &&. Lastly, this can help with code clearness since the following can be avoided

let x = fn_long();
let y = fn_other();

if 5 < x && x < 10 && y <= x && 5 < y {
    ...
}

and replaced with:

if 5 < fn_other() <= fn_long() < 10 {
}

where the return values of any non_constant is held in reserve so that the function isn't called multiple times.

@burdges
Copy link

burdges commented Jul 26, 2017

It's sounds problematic since bool already implements PartialOrd, PartialEq, etc. These operators would need to become hostile to any associativity, including their current one, which likely breaks some existing code, albeit code that perhaps rustfmt should change.

@le-jzr
Copy link

le-jzr commented Jul 26, 2017

bool already implements PartialOrd

Huh. It does. I had to check for myself, since I couldn't believe anyone could have had such a terrible idea.

However, such chaining of operators is still possible to implement, since it's currently rejected as an error. I'm not saying I want it to be implemented, I'm actually against the idea, but it's not a technical problem.

@Nokel81
Copy link
Contributor Author

Nokel81 commented Jul 26, 2017

At least for LT, GT, LTE, GTE boolean cannot be a type on a side of one of the operators.

@burdges
Copy link

burdges commented Jul 26, 2017

Actually (1<0) < true compiles just fine. It's interesting that "chained comparison operators require parentheses" currently, so yes parsing this works.

@joshtriplett
Copy link
Member

joshtriplett commented Jul 27, 2017

The best use case I've seen for this is a range bound, like lower <= x < upper. However, to me, that seems better done with Range::contains: #1434

What other use cases would fit this, that wouldn't be more clearly written some other way?

@burdges
Copy link

burdges commented Jul 27, 2017

I've no strong feelings on this since the compiler already prevents chained comparison operators. I'm curious though : What languages do this currently?

@Nokel81
Copy link
Contributor Author

Nokel81 commented Jul 27, 2017

Python that I know of

@strega-nil
Copy link

strega-nil commented Jul 27, 2017

@joshtriplett it's more useful for generic code than anything (also, every language I know of has the relational operators for bool)

@cramertj
Copy link
Member

@ubsan Did you mean to direct your response above to @le-jzr ?

@xen0n
Copy link
Contributor

xen0n commented Jul 30, 2017

In Python a < x < b is just sugar for a < x and x < b (although the resulting bytecode is slightly different). Counter-intuitively, a < x > b also works, so the comparison chaining is really just fusing at its heart.

Don't know enough to judge from the rustc implementation's perspective, though.

@NXTangl
Copy link

NXTangl commented Aug 3, 2017

I feel like this could be an optional thing, enabled by some #[pragma]. I mean, we already special-case the parse, just add a few hooks to make it like the Python implementation. OTOH, there's also semantics to consider. Like, does this syntax short-circuit? If I write a < b < someComputation() and at runtime a >= b, will someComputation() run, or not? And do we allow this for chaining more than two compares (e.g. a < b < c < d)?

@Nokel81
Copy link
Contributor Author

Nokel81 commented Aug 3, 2017

If it was to work like Python then in the first case the function would not run since the operators are lazy and I don't see why not allowing chaining of multiple compares since it would be like concatenating multiple comparisons with short circuit and

@NXTangl
Copy link

NXTangl commented Aug 3, 2017

I meant more in the sense of "this adds unnecessary complexity to our language specification for a feature that's pretty much optional" But looking back, there's really no reason not to do it, certainly not if it's a #[pragma]-based opt-in.

@strega-nil
Copy link

@cramertj yeah lol, sorry.

Anyways, I like this idea, it's quite nice and follows, at least my, intuition.

@mbrubeck
Copy link
Contributor

cc #561.

@Centril Centril added the T-lang Relevant to the language team, which will review and decide on the RFC. label Dec 6, 2017
@ylxdzsw
Copy link

ylxdzsw commented Jul 24, 2020

Just to add that Julia also allows this https://docs.julialang.org/en/v1/manual/mathematical-operations/#Chaining-comparisons-1
It happens to support more unicode operators and so is even more useful. Example 2 ∈ [2,3] ⊆ [2,3,4] evaluates true.

@lebensterben
Copy link

In real world no one writes 1 < 2 >= -1 except for confusing readers. The most common cases only contain homogeneous chains. So the syntax in Julia seems very bad to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests