-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Clarify range's exclusivity. #15217
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
Clarify range's exclusivity. #15217
Conversation
/// Returns an iterator over the given range, starting with `start` and ending | ||
/// at `stop`. | ||
/// | ||
/// The range is inclusive with regard to `start`, and exclusive with regard to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this really explains the full rationale (although I'm not sure how much API docs can or should explain rationale, since the goal of API docs is to learn how to use them rather than understand their design principles). Starting at zero is really a special case of the more general point that half-open ranges compose cleanly. For example,
for n in range(0, 10u) { f(n); }
is equivalent to
for n in range(0, 6u) { f(n); }
for n in range(6u, 10u) { f(n); }
Edit: Fixed an unbelievably bad bug in the example, which is actually the whole point! Using literals probably doesn't demonstrate the composability that well since you could always just pick different literals. The critical point, which I botched at first, is that you use the same single number to divide up the interval without having to do any arithmetic. Formally, given a half-open range [a, b), you can take any i in the range and [a, b) is equivalent to [a, i) o [i, b). Commonly this shows up when picking, say, a mid-point in a divide-and-conquer algorithm:
let mid = ...;
for n in range(start, mid) { ... }
for n in range(mid, end) { ... }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahhhh interesting.
I do think that rationale is good, because it helps you build the mental model for how the API is intended to be used.
The Here I tried a different approach though if you will want an example like this here I'm not sure:
Questions regarding this notation will probably come up often with new programmers and people used to one based indexing. |
That's not bad. |
I would agree that keeping the original like with the [start, stop) notation and following that up with further explanation would be useful. I also liked the note above "over the range [start, stop) (starting at start (inclusive), and ending at stop (exclusive))." How easy is it to get to this page? My first points of contact were with the tutorial (http://doc.rust-lang.org/tutorial.html) and the reference (http://doc.rust-lang.org/rust.html). I think it could be worth also clarifying the aspects of range in those docs as well, in terms of a couple of examples and a mention about the exclusive nature of the second parameter. |
There's a separate iterator tutorial where extensive coverage of the various |
Perhaps a link to Edsger Dijkstra's classic explanation, why numbering should start at zero, is appropriate? I'm sure readers of the documentation will appreciate such enhancement of their erudition. :) |
internal: convert unwrap to except and add a debug log Remove an unsafe unwrap that can cause crashes if the value is a `SendError`. This is my first PR on this repo, please let me know if there is anything I can improve or details I can provide.
Inspired by http://www.reddit.com/r/rust/comments/298js2/what_is_the_rationale_behind_the_second_parameter/