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

Deprecate [T]::rotate in favor of [T]::rotate_{left,right}. #46777

Merged
merged 1 commit into from
Jan 10, 2018

Conversation

frewsxcv
Copy link
Member

@frewsxcv frewsxcv commented Dec 16, 2017

Background

Slices currently have an unstable rotate method which rotates
elements in the slice to the left N positions. Here is the
tracking issue for this unstable feature.

let mut a = ['a', 'b' ,'c', 'd', 'e', 'f'];
a.rotate(2);
assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);

Proposal

Deprecate the rotate method and introduce rotate_left and
rotate_right methods.

let mut a = ['a', 'b' ,'c', 'd', 'e', 'f'];
a.rotate_left(2);
assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
let mut a = ['a', 'b' ,'c', 'd', 'e', 'f'];
a.rotate_right(2);
assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);

Justification

I used this method today for my first time and (probably because I’m a
naive westerner who reads LTR) was surprised when the docs mentioned that
elements get rotated in a left-ward direction. I was in a situation
where I needed to shift elements in a right-ward direction and had to
context switch from the main problem I was working on and think how much
to rotate left in order to accomplish the right-ward rotation I needed.

Ruby’s Array.rotate shifts left-ward, Python’s deque.rotate shifts
right-ward. Both of their implementations allow passing negative numbers
to shift in the opposite direction respectively. The current rotate
implementation takes an unsigned integer argument which doesn't allow
the negative number behavior.

Introducing rotate_left and rotate_right would:

  • remove ambiguity about direction (alleviating need to read docs 😉)
  • make it easier for people who need to rotate right

@rust-highfive
Copy link
Collaborator

r? @BurntSushi

(rust_highfive has picked a reviewer for you, use r? to override)

@frewsxcv frewsxcv added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Dec 16, 2017
@frewsxcv
Copy link
Member Author

If this needs to go through an RFC, let me know and I can throw one together 💁‍♂️

Also cc @scottmcm since you wrote the initial rotate implementation. Thank you soo much for writing [T]::rotate, I used it today for the latest Advent of Code problem ❤️

@kennytm kennytm added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 17, 2017
Copy link
Member

@scottmcm scottmcm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems good to me. The left/right is probably better since the takes a number (as opposed to some "position" concept, where rotating the two sides without mentioning a direction is the better API).

///
/// Takes linear (in `self.len()`) time.
///
/// # Examples
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider including an example that rotates a subslice, since that seems to be such a common confusion (see the recent changes to copy_from_slice and such).

/// ```
#[unstable(feature = "slice_rotate", issue = "41891")]
pub fn rotate(&mut self, mid: usize) {
core_slice::SliceExt::rotate(self, mid);
pub fn rotate_right(&mut self, mid: usize) {
Copy link
Member

@scottmcm scottmcm Dec 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more thought here: rotate (and thus rotate_left) used mid for the parameter because it has a useful interpretation as an index, the same as split_at (which uses the same parameter name).

rotate_right, however, doesn't have that same meaning, so it should have a different name. I propose k, the letter used in EoP (the book I was following while trying various possible implementations) and common in a quick search of specifically to-the-right rotation problems online.

@frewsxcv
Copy link
Member Author

@scottmcm thanks for the feedback! both your comments have been addressed in the latest force push

@scottmcm
Copy link
Member

Error looks non-transient, though weird:

[00:02:45]    Compiling alloc v0.0.0 (file:///checkout/src/liballoc)
[00:02:45] error: missing `fn`, `type`, or `const` for impl-item declaration
[00:02:45]     --> /checkout/src/liballoc/slice.rs:1437:33
[00:02:45]      |
[00:02:45] 1437 |       /// a[1..5].rotate_right(1);
[00:02:45]      |  _________________________________^
[00:02:45] 1438 | | l   /// assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
[00:02:45]      | |  missing `fn`, `type`, or `const`
[00:02:45] 
[00:02:48] error: aborting due to previous error
[00:02:48] 
[00:02:48] error: Could not compile `alloc`.

https://github.com/rust-lang/rust/pull/46777/files#diff-773807740b9d7f176c85b4e2e34b2607R1437

/// ```
/// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
/// a[1..5].rotate_right(1);
l /// assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an l at the start of the line 😄

Also, the code example is missing #![feature(slice_rotate)].

@frewsxcv
Copy link
Member Author

ci errors fixed in the latest force push

@@ -650,6 +653,16 @@ impl<T> SliceExt for [T] {
}
}

fn rotate_right(&mut self, mid: usize) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: k here too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good call! addressed in the latest force push

Background
==========

Slices currently have an unstable [`rotate`] method which rotates
elements in the slice to the _left_ N positions. [Here][tracking] is the
tracking issue for this unstable feature.

```rust
let mut a = ['a', 'b' ,'c', 'd', 'e', 'f'];
a.rotate(2);
assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
```

Proposal
========

Deprecate the [`rotate`] method and introduce `rotate_left` and
`rotate_right` methods.

```rust
let mut a = ['a', 'b' ,'c', 'd', 'e', 'f'];
a.rotate_left(2);
assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
```

```rust
let mut a = ['a', 'b' ,'c', 'd', 'e', 'f'];
a.rotate_right(2);
assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
```

Justification
=============

I used this method today for my first time and (probably because I’m a
naive westerner who reads LTR) was surprised when the docs mentioned that
elements get rotated in a left-ward direction. I was in a situation
where I needed to shift elements in a right-ward direction and had to
context switch from the main problem I was working on and think how much
to rotate left in order to accomplish the right-ward rotation I needed.

Ruby’s `Array.rotate` shifts left-ward, Python’s `deque.rotate` shifts
right-ward. Both of their implementations allow passing negative numbers
to shift in the opposite direction respectively.

Introducing `rotate_left` and `rotate_right` would:

- remove ambiguity about direction (alleviating need to read docs 😉)
- make it easier for people who need to rotate right

[`rotate`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rotate
[tracking]: rust-lang#41891
@ollie27
Copy link
Member

ollie27 commented Dec 27, 2017

Are "left" and "right" the correct terms to use here or does this suffer from the same issue as trim_left and trim_right: #30459? Perhaps rotate_forwards and rotate_backwards would be better as slices have a concept of front and back but I don't think they really have a concept of left and right.

@retep998
Copy link
Member

Given that slices can be trivially represented as [a, b, c] it is very clear where the left is and where the right is. Forwards and backwards is much trickier to understand in my opinion.

@ollie27
Copy link
Member

ollie27 commented Dec 27, 2017

VecDeque uses front and back in its method names. Ideally these rotate methods would be added to VecDeque as well so using left and right would seem a bit inconsistent there.

@frewsxcv
Copy link
Member Author

Does 'forward' mean 'towards the back' or 'towards the front'? I could see arguments for either

@frewsxcv
Copy link
Member Author

Okay, I'm embarrassed now since apparently the definition of 'forward' is literally "toward the front" in the dictionary. I guess that would means 'forward' is rotate-left?

@scottmcm
Copy link
Member

scottmcm commented Dec 27, 2017

@frewsxcv FWIW, I also was uncertain, perhaps since "iterating forward" is starts at the front and moves toward the back...

@frewsxcv
Copy link
Member Author

frewsxcv commented Jan 2, 2018

anyone from @rust-lang/libs have thoughts about this?

@mbrubeck
Copy link
Contributor

mbrubeck commented Jan 2, 2018

Regarding alternate names, there was previous discussion in #41891.

@alexcrichton alexcrichton added S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 2, 2018
@alexcrichton
Copy link
Member

@bors: r+

Thanks for the PR and thorough explanation @frewsxcv! We discussed this at @rust-lang/libs triage today and it got the green light from everyone.

@bors
Copy link
Contributor

bors commented Jan 10, 2018

📌 Commit 66ef6b9 has been approved by alexcrichton

@frewsxcv
Copy link
Member Author

@bors rollup

frewsxcv added a commit to frewsxcv/rust that referenced this pull request Jan 10, 2018
…chton

Deprecate [T]::rotate in favor of [T]::rotate_{left,right}.

Background
==========

Slices currently have an **unstable** [`rotate`] method which rotates
elements in the slice to the _left_ N positions. [Here][tracking] is the
tracking issue for this unstable feature.

```rust
let mut a = ['a', 'b' ,'c', 'd', 'e', 'f'];
a.rotate(2);
assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
```

Proposal
========

Deprecate the [`rotate`] method and introduce `rotate_left` and
`rotate_right` methods.

```rust
let mut a = ['a', 'b' ,'c', 'd', 'e', 'f'];
a.rotate_left(2);
assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
```

```rust
let mut a = ['a', 'b' ,'c', 'd', 'e', 'f'];
a.rotate_right(2);
assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
```

Justification
=============

I used this method today for my first time and (probably because I’m a
naive westerner who reads LTR) was surprised when the docs mentioned that
elements get rotated in a left-ward direction. I was in a situation
where I needed to shift elements in a right-ward direction and had to
context switch from the main problem I was working on and think how much
to rotate left in order to accomplish the right-ward rotation I needed.

Ruby’s `Array.rotate` shifts left-ward, Python’s `deque.rotate` shifts
right-ward. Both of their implementations allow passing negative numbers
to shift in the opposite direction respectively. The current `rotate`
implementation takes an unsigned integer argument which doesn't allow
the negative number behavior.

Introducing `rotate_left` and `rotate_right` would:

- remove ambiguity about direction (alleviating need to read docs 😉)
- make it easier for people who need to rotate right

[`rotate`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rotate
[tracking]: rust-lang#41891
bors added a commit that referenced this pull request Jan 10, 2018
Rollup of 5 pull requests

- Successful merges: #46762, #46777, #47262, #47285, #47301
- Failed merges:
@bors bors merged commit 66ef6b9 into rust-lang:master Jan 10, 2018
@frewsxcv frewsxcv deleted the frewsxcv-rotate branch January 10, 2018 12:57
@Restioson
Copy link

Just a note, the docs still say rotate.

@frewsxcv
Copy link
Member Author

the new methods haven't hit stable or beta yet, so youll need a nightly compiler and be looking at the nightly docs

https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.rotate_left

@Restioson
Copy link

Ah sorry, didn't notice that. I'd assumed that since the stable docs had nightly methods they'd be up to date with them.

@frewsxcv
Copy link
Member Author

frewsxcv commented Jan 17, 2018

Stable docs do render unstable methods, but these new methods need to ride the release train from nightly to beta and stable before the methods show up in beta and stable docs

@Restioson
Copy link

Ah yes this makes sense, I forget that the thing blocking nightly features from stable is specifically feature gates. Thanks :)

kennytm added a commit to kennytm/compiletest-rs that referenced this pull request Feb 27, 2018
The `rotate` method has been deprecated in favor of `rotate_left` and `rotate_right` since rust-lang/rust#46777, and will be deleted in rust-lang/rust#48450.
laumann pushed a commit to Manishearth/compiletest-rs that referenced this pull request Feb 27, 2018
The `rotate` method has been deprecated in favor of `rotate_left` and `rotate_right` since rust-lang/rust#46777, and will be deleted in rust-lang/rust#48450.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.