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 `..=` inclusive ranges (RFC #1192) -- originally `...` #28237

Closed
nikomatsakis opened this Issue Sep 4, 2015 · 331 comments

Comments

Projects
None yet
@nikomatsakis
Copy link
Contributor

nikomatsakis commented Sep 4, 2015

Current status

We are planning to to change the syntax for inclusive ranges and patterns to ..=. The ... syntax in patterns is stable and will remain (silently) deprecated for the time being; rustfmt can rewrite ... to ..=. This comes after much discussion. See this comment for justification.

No more syntax discussion should be had in this thread. Any different proposals of exclusive range syntax should take place on the user's forum or internals forum, after you have read all existing comments and their rationale here. Notably, breaking backwards compatibility is a non-starter.

Steps to take

@JohanLarsson

This comment has been minimized.

Copy link

JohanLarsson commented Oct 6, 2015

Maybe a..b| or a..b]

@alexcrichton alexcrichton added the T-lang label Feb 18, 2016

bors added a commit that referenced this issue Mar 5, 2016

Auto merge of #30884 - durka:inclusive-ranges, r=aturon
This PR implements [RFC 1192](https://github.com/rust-lang/rfcs/blob/master/text/1192-inclusive-ranges.md), which is triple-dot syntax for inclusive range expressions. The new stuff is behind two feature gates (one for the syntax and one for the std::ops types). This replaces the deprecated functionality in std::iter. Along the way I simplified the desugaring for all ranges.

This is my first contribution to rust which changes more than one character outside of a test or comment, so please review carefully! Some of the individual commit messages have more of my notes. Also thanks for putting up with my dumb questions in #rust-internals.

- For implementing `std::ops::RangeInclusive`, I took @Stebalien's suggestion from rust-lang/rfcs#1192 (comment). It seemed to me to make the implementation easier and increase type safety. If that stands, the RFC should be amended to avoid confusion.
- I also kind of like @glaebhoerl's [idea](rust-lang/rfcs#1254 (comment)), which is unified inclusive/exclusive range syntax something like `x>..=y`. We can experiment with this while everything is behind a feature gate.
- There are a couple of FIXMEs left (see the last commit). I didn't know what to do about `RangeArgument` and I haven't added `Index` impls yet. Those should be discussed/finished before merging.

cc @Gankro since you [complained](https://www.reddit.com/r/rust/comments/3xkfro/what_happened_to_inclusive_ranges/cy5j0yq)
cc #27777 #30877 #1192 rust-lang/rfcs#1254
relevant to #28237 (tracking issue)

bors added a commit that referenced this issue Mar 6, 2016

Auto merge of #30884 - durka:inclusive-ranges, r=aturon
This PR implements [RFC 1192](https://github.com/rust-lang/rfcs/blob/master/text/1192-inclusive-ranges.md), which is triple-dot syntax for inclusive range expressions. The new stuff is behind two feature gates (one for the syntax and one for the std::ops types). This replaces the deprecated functionality in std::iter. Along the way I simplified the desugaring for all ranges.

This is my first contribution to rust which changes more than one character outside of a test or comment, so please review carefully! Some of the individual commit messages have more of my notes. Also thanks for putting up with my dumb questions in #rust-internals.

- For implementing `std::ops::RangeInclusive`, I took @Stebalien's suggestion from rust-lang/rfcs#1192 (comment). It seemed to me to make the implementation easier and increase type safety. If that stands, the RFC should be amended to avoid confusion.
- I also kind of like @glaebhoerl's [idea](rust-lang/rfcs#1254 (comment)), which is unified inclusive/exclusive range syntax something like `x>..=y`. We can experiment with this while everything is behind a feature gate.
- There are a couple of FIXMEs left (see the last commit). I didn't know what to do about `RangeArgument` and I haven't added `Index` impls yet. Those should be discussed/finished before merging.

cc @Gankro since you [complained](https://www.reddit.com/r/rust/comments/3xkfro/what_happened_to_inclusive_ranges/cy5j0yq)
cc #27777 #30877 #1192 rust-lang/rfcs#1254
relevant to #28237 (tracking issue)
@bakirov

This comment has been minimized.

Copy link

bakirov commented Mar 21, 2016

I think this will open up the way for the new kind of unpredictable errors in future because of a simple typo (.. vs ...). Better if it was .... (4 periods). This way it is less error-prone to the human factor, imo.

@canndrew

This comment has been minimized.

Copy link
Contributor

canndrew commented May 9, 2016

I think rust-lang/rfcs#1592 and rust-lang/rfcs#1582 combined make a case for using the ..= syntax instead. Unless someone can think of better syntax than (head..., tail) for expanding a tuple at the front of a larger tuple.

@kornelski

This comment has been minimized.

Copy link
Contributor

kornelski commented Jul 1, 2016

I've found this issue because I had off-by-one-dot error in my code when I've meant to use exclusive range.

👎 for the ... syntax. I think having an easy-to-mistype syntax that causes off-by-one errors would be a footgun.

The functionality is useful though, so I'd be happy to have it with a different syntax, e.g. ..=

@andrewtj

This comment has been minimized.

Copy link

andrewtj commented Jul 2, 2016

Is the syntax for this an open question? Since ... is already in match statements I assumed that ship had sailed.

@hoodie

This comment has been minimized.

Copy link
Contributor

hoodie commented Jul 2, 2016

I'd personally prefer the ... inclusive range, however since there is already the .. exclusive version, I I see the potential for problems. After looking at #23635 though I'd rather deprecate .. and only allow ... though.

@kornelski

This comment has been minimized.

Copy link
Contributor

kornelski commented Jul 2, 2016

I use inclusive ranges a lot for equivalent of C-like for loops for i in 0..foo.len() where it fits perfectly, so I'd prefer that one to stay (I need this, because Rust's iterators are "1-dimensional" and often too awkward to use with 2D arrays or non-linear iteration).

The problem with overflow for inclusive ranges looks silly, but in practice I never ran into this problem, because Rust is annoying to use with any type other than usize. If I didn't cast when creating the range for i in 0..(len as usize), then I'd have to use i as usize half a dozen times inside the loop anyway.

Since this syntax is still feature-gated I hope the ship hasn't sailed.

@hoodie

This comment has been minimized.

Copy link
Contributor

hoodie commented Jul 2, 2016

Considering that swift uses ... for inclusive and ..< for exclusive ranges, using ..= for inclusive seems pretty reasonable.

@ottworks

This comment has been minimized.

Copy link

ottworks commented Jul 16, 2016

I don't have any useful insights, but I'd like for inclusive ranges to exit "experimental" status. As I was going through Rust By Example, I found one snippet that could benefit from this:

fn fizzbuzz_to(n: u32) {
    for n in 1..n + 1 {
        fizzbuzz(n);
    }
}
@Kerollmops

This comment has been minimized.

Copy link
Contributor

Kerollmops commented Jul 17, 2016

Up ? 😄

@durka

This comment has been minimized.

Copy link
Contributor

durka commented Aug 1, 2016

I want to write an RFC for a ..= b syntax and generalized ranges. I've started a discuss thread to talk about how such ranges would be represented in the standard library.

@tengwar

This comment has been minimized.

Copy link

tengwar commented Aug 14, 2016

IMHO ..= looks weird. Swift's approach of ... and ..< looks better to me, because I prefer the ellipsis over two dots - ellipsis stands for omission and we are omitting the numbers between the start and the end of the range.

I still think ... and .. was good enough. You have 1 character difference, so the mistake is harder to make than +/- or x/y or whatever.

@jimblandy

This comment has been minimized.

Copy link
Contributor

jimblandy commented Aug 14, 2016

Since I misunderstood this myself earlier (and so deleted my comment):

Per Rust's RFC process, this proposal has already been reviewed, discussed, and approved in RFC pull request 1192. The present issue tracks the implementation of what was previously decided there. The discussion covered many of the points people are raising here: alternative syntax (including no new syntax), the contrast with Ruby's similar operators, etc.

If you feel strongly that the feature should be different, I think you need to take it through the same RFC process, because that's how changes to the language get made. But this issue isn't the place for that.

@shepmaster

This comment has been minimized.

Copy link
Member

shepmaster commented Aug 14, 2016

@jimblandy maybe we should have @nikomatsakis edit that polite reminder and guidance into the first comment in Really Big Print. 😇

@joshtriplett

This comment has been minimized.

Copy link
Member

joshtriplett commented Aug 14, 2016

@shepmaster That would probably be a good thing to add to a template used to file all tracking issues.

@nrc nrc added the I-nominated label Aug 17, 2016

@nrc

This comment has been minimized.

Copy link
Member

nrc commented Aug 17, 2016

Nominating for discussion/possible FCP

@nikomatsakis

This comment has been minimized.

Copy link
Contributor Author

nikomatsakis commented Aug 22, 2016

We discussed this in the @rust-lang/lang meeting. There was a general sense of unhappiness with this feature -- we considered moving to deprecate, but decided to hold off on that for the time being. There are two major objections to ... as it stands:

  • the ease of confusion between .. and ...;
  • @aturon has been thinking that it would be better to have a more "fully capable" range syntax -- this could also be used in APIs like btree iteration and so forth.

To that end, we were wondering if someone would be willing to drive forward an RFC that enabled a more general syntax like that let people specify precisely whether the lower- and upper-bounds would be inclusive or exclusive. I think @aturon would be happy to work with someone on such an RFC.

kumbayo added a commit to kumbayo/intellij-rust that referenced this issue Mar 11, 2018

GRAM: Support the new '..=' syntax for inclusive ranges
Inclusive ranges are currently a unstable feature of Rust.
'..=' for ranges requires #![feature(inclusive_range_syntax)]
'..=' for range patterns requires #![feature(dotdoteq_in_patterns)]

The nightly version of Rust does not accept the previous syntax
'...' for inclusive ranges anymore.
(For range patterns the old syntax is still supported)

It produces the following output:
error: `...` syntax cannot be used in expressions
help: Use `..` if you need an exclusive range (a < b)
help: or `..=` if you need an inclusive range (a <= b)

We still support the old '...' syntax for both ranges and range patterns.

See the tracking issue rust-lang/rust/issues/28237 for '..=' inclusive
ranges. (RFC 1192)

Fixes intellij-rust#2335

Undin added a commit to intellij-rust/intellij-rust that referenced this issue Mar 11, 2018

GRAM: Support the new '..=' syntax for inclusive ranges
Inclusive ranges are currently a unstable feature of Rust.
'..=' for ranges requires #![feature(inclusive_range_syntax)]
'..=' for range patterns requires #![feature(dotdoteq_in_patterns)]

The nightly version of Rust does not accept the previous syntax
'...' for inclusive ranges anymore.
(For range patterns the old syntax is still supported)

It produces the following output:
error: `...` syntax cannot be used in expressions
help: Use `..` if you need an exclusive range (a < b)
help: or `..=` if you need an inclusive range (a <= b)

We still support the old '...' syntax for both ranges and range patterns.

See the tracking issue rust-lang/rust/issues/28237 for '..=' inclusive
ranges. (RFC 1192)

Fixes #2335

(cherry picked from commit 6f84a9c)

bors added a commit that referenced this issue Mar 15, 2018

Auto merge of #47813 - kennytm:stable-incl-range, r=nrc
Stabilize inclusive range (`..=`)

Stabilize the followings:

* `inclusive_range` — The `std::ops::RangeInclusive` and `std::ops::RangeInclusiveTo` types, except its fields (tracked by #49022 separately).
* `inclusive_range_syntax` — The `a..=b` and `..=b` expression syntax
* `dotdoteq_in_patterns` — Using `a..=b` in a pattern

cc #28237
r? @rust-lang/lang

bors added a commit that referenced this issue Mar 15, 2018

Auto merge of #47813 - kennytm:stable-incl-range, r=nrc
Stabilize inclusive range (`..=`)

Stabilize the followings:

* `inclusive_range` — The `std::ops::RangeInclusive` and `std::ops::RangeInclusiveTo` types, except its fields (tracked by #49022 separately).
* `inclusive_range_syntax` — The `a..=b` and `..=b` expression syntax
* `dotdoteq_in_patterns` — Using `a..=b` in a pattern

cc #28237
r? @rust-lang/lang

alercah added a commit to alercah/book that referenced this issue Mar 16, 2018

alercah added a commit to alercah/book that referenced this issue Mar 16, 2018

@mominul

This comment has been minimized.

Copy link

mominul commented Mar 29, 2018

inclusive range has been stabilized as #47813 pull request has been merged but it is not in the 1.25 release, why? Though the pull request was merged on 16th March

@kennytm

This comment has been minimized.

Copy link
Member

kennytm commented Mar 29, 2018

@mominul a feature is available only after it has been merged into master branch, thus ..= is available starting from 1.26, not 1.25.

@clarcharr

This comment has been minimized.

Copy link
Contributor

clarcharr commented Mar 29, 2018

That way you can test them on beta and nightly before they get pushed to stable.

@mominul

This comment has been minimized.

Copy link

mominul commented Mar 29, 2018

Thanks for the inputs @kennytm and @clarcharr ! Rust 1.26 release is definitely not boring at least for me! 😄

@ElectricCoffee

This comment has been minimized.

Copy link

ElectricCoffee commented Apr 1, 2018

I know it's too late to pitch in on this discussion, but why not omit the .. syntax entirely and use words instead?

In Scala you have 1 to 4 which generates [1, 2, 3, 4], 1 until 4 which generates [1, 2, 3], and an optional by keyword that follows that indicates step size: 1 to 10 by 2 = [1, 3, 5, 7, 9].

This both makes the intent more clear, and avoids the "off-by-one" error that everyone seems so concerned about.

Granted, this does break all the existing code, if the original syntax doesn't stay supported.

@daboross

This comment has been minimized.

Copy link
Contributor

daboross commented Apr 1, 2018

@ElectricCoffee in rust ranges support all types though, not just numbers. I think we'd need to introduce to and until as keywords in order to support that, and that would be a much bigger breaking change.

It works well in Scala, but Rust's design choices differ largely.

@timvisee

This comment has been minimized.

Copy link
Contributor

timvisee commented Apr 1, 2018

@ElectricCoffee although l would like the feeling of that, I don't think it's desired to add the additional keywords for it.

I believe built-in language keywords should be kept at a minimum, as they might collide with function or variable names.

Although to and until aren't words used in the std (as far as I know), I'm sure they're common words used in to other crates and projects.

@ElectricCoffee

This comment has been minimized.

Copy link

ElectricCoffee commented Apr 2, 2018

@daboross that's actually a fair point that I didn't consider, though that being said, a .. b does in a sense mean a to b, regardless of what a and b actually are.

And yeah, @timvisee they probably are.

@Boscop

This comment has been minimized.

Copy link

Boscop commented Apr 3, 2018

@ElectricCoffee But if to meant ..= and until meant .. you'd have to write a until b, not a to b instead of a .. b. As you can see, it's not "more" intuitive to use these words than operators.. But it would be more verbose to write until everywhere that .. is used, because it's much more common than ..= (so if words were used, .. should be assigned the shorter word).

@ElectricCoffee

This comment has been minimized.

Copy link

ElectricCoffee commented Apr 3, 2018

And you're absolutely right about that @Boscop, it was however just an example of how words could be done.

I believe I've seen to for exclusive and upto for inclusive in some languages as well.
It was all meant as an idea.

In Scala, the inclusive range is more used than the exclusive one, and thus is given the shorter word.

@hyst329

This comment has been minimized.

Copy link

hyst329 commented Apr 5, 2018

@timvisee One simply can use a.to(b) and a.until(b), no additional keywords are needed (and it doesn't make the syntax much more clumsy).

@timvisee

This comment has been minimized.

Copy link
Contributor

timvisee commented Apr 5, 2018

@hyst329 I didn't even think about that. I must say, I really like that idea! You are indeed correct.

I don't believe though that this would be a proper full replacement for the current (/new) syntax. But it would be a nice addition.

@ssokolow

This comment has been minimized.

Copy link

ssokolow commented Apr 5, 2018

I have to agree with Boscop's comment about intuitiveness. Aside from words like "including" and "except", day-to-day English doesn't really distinguish between inclusive and exclusive ranges strongly enough for there to be a ready-made shortcut.

Unless it's used in a context where "A through B" is also used, it's ambiguous whether "A to B" means an inclusive or exclusive range in day-to-day speech here in southern Ontario, Canada, and "until" is associated with time strongly enough that, when used in this looser sense, it's unclear whether the "event" that "until" associates with is "until we see X" or "until we've processed X".

@daboross

This comment has been minimized.

Copy link
Contributor

daboross commented Apr 5, 2018

@hyst329 Having them as methods would limit ranges to number types, though. I'd really rather not have one syntax for ranges of numbers and another for ranges of other things.

I guess we could add a new catch-all trait to the prelude for creating ranges, but that's still verging on a breaking change for things which have actual to and until methods.

@durka

This comment has been minimized.

Copy link
Contributor

durka commented Apr 5, 2018

@shepmaster

This comment has been minimized.

Copy link
Member

shepmaster commented Apr 5, 2018

Yeah, we've had 300+ comments on this issue, and the very first comment says:

no more syntax discussion should be had in this thread. Any different proposals of exclusive range syntax should take place on the user's forum or internals forum, after you have read all existing comments and their rationale here. Notably, breaking backwards compatibility is a non-starter.

I'm going to lock this issue for now, sorry if I'm stepping on any toes!

@rust-lang rust-lang locked as resolved and limited conversation to collaborators Apr 5, 2018

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented May 26, 2018

I believe that everything covered by this issue is done. Please reopen and update the checklist in the issue’s original message if there’s something else.

@SimonSapin SimonSapin closed this May 26, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.