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

Tracking issue for ..= inclusive ranges (RFC #1192) -- originally ... #28237

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

Tracking issue for ..= inclusive ranges (RFC #1192) -- originally ... #28237

nikomatsakis opened this issue Sep 4, 2015 · 331 comments

Comments

@nikomatsakis
Copy link
Contributor

@nikomatsakis 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
Copy link

@JohanLarsson JohanLarsson commented Oct 6, 2015

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

bors added a commit that referenced this issue Mar 5, 2016
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
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
Copy link

@bakirov 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
Copy link
Contributor

@canndrew 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
Copy link
Contributor

@kornelski 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
Copy link

@andrewtj 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
Copy link
Contributor

@hoodie 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
Copy link
Contributor

@kornelski 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
Copy link
Contributor

@hoodie hoodie commented Jul 2, 2016

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

@ottworks
Copy link

@ottworks 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
Copy link
Contributor

@Kerollmops Kerollmops commented Jul 17, 2016

Up ? 😄

@durka
Copy link
Contributor

@durka 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
Copy link

@tengwar 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
Copy link
Contributor

@jimblandy 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
Copy link
Member

@shepmaster 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
Copy link
Member

@joshtriplett 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
Copy link
Member

@nrc nrc commented Aug 17, 2016

Nominating for discussion/possible FCP

@nikomatsakis
Copy link
Contributor Author

@nikomatsakis 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
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
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
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
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
Copy link
Contributor

@mominul 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
Copy link
Member

@kennytm 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.

@clarfonthey
Copy link
Contributor

@clarfonthey clarfonthey commented Mar 29, 2018

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

@mominul
Copy link
Contributor

@mominul 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
Copy link

@ElectricCoffee 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
Copy link
Contributor

@daboross 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
Copy link
Contributor

@timvisee 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
Copy link

@ElectricCoffee 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
Copy link

@Boscop 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
Copy link

@ElectricCoffee 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.

@trolley813
Copy link

@trolley813 trolley813 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
Copy link
Contributor

@timvisee 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
Copy link

@ssokolow 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
Copy link
Contributor

@daboross 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
Copy link
Contributor

@durka durka commented Apr 5, 2018

@shepmaster
Copy link
Member

@shepmaster 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
Copy link
Contributor

@SimonSapin 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.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet