-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Align the count parameter of splitn with other languages #979
Align the count parameter of splitn with other languages #979
Conversation
See also rust-lang/rust#14899 |
/cc @aturon or @alexcrichton . This proposes to change currently-stable methods in a backwards-incompatible manner. |
I'm somewhat ambivalent on this one way or the other. I find the I would personally vote for just breaking code without jumping through hoops to nudge crates to update. |
FWIW, the |
I thought I had commented on this RFC a week ago, but my comment seems to be gone! I definitely agree that the proposed semantics is the more intuitive one -- I've mistakenly assumed these semantics in the past, and seen other people do the same. @alexcrichton makes a good point about the 0 case; we would probably want to panic (i.e. treat that as a contract violation). But I don't think that's a deal breaker or anything. My bigger concern is: how can we roll this out in the short time before beta without silently breaking a lot of code? @alexcrichton, I lack your confidence that we can just change the semantics, but maybe you can elaborate on how you see that working out? Otherwise, we might need to consider some multi-step deprecation (assuming we want to stick with the current names), which would be a bit painful and time consuming. |
I'm in favor of the change. The current functionality loses information: there is no way to preserve the tail without doing a full split+rejoin of the tail. I also find the proposed functionality more natural and have explicitly relied on it a number of times in C# whereas I've had to work around JavaScript's functionality (see below). In mostly valid Rust (I can't find a join method in the std library), the current functionality makes maintaining the tail difficult: let a: Vec<_> = "a,b,c"
.split(',')
.iter()
.take(1)
.chain([a.iter().skip(1).join(',')].iter())
.collect();
assert_eq!(a, ["a", "b,c"]); With the proposed functionality the tail is maintained and can easily be trimmed with let a: Vec<_> = "a,b,c".splitn(2, ',').collect();
assert_eq!(a, ["a", "b,c"]);
let n = 2
let a: Vec<_> = "a,b,c".splitn(n - 1, ',').take(n).collect();
assert_eq!(a, ["a", "b"]); As a side note JavaScript provides another variant where 'a,b,c'.split(',', 2)
["a", "b"] |
If we accept this RFC I'd personally vote to accept it as-is where the integer parameter is the precise number of times the iterator will return
I wouldn't necessarily say I had a grand vision here, mostly it was just that tests would catch this bug and general usage would weed out cases pretty quickly. This is a pretty minor method and I feel it's not worth an elaborate migration plan. |
@alexcrichton Ah, I missed that point about 0. That seems OK. I'm potentially OK with a direct change, but we would need to advertise it widely. |
I'm vaguly 👍 about this RFC. Consistency with more languages is good. I agree with @alexcrichton that it probably doesn't need an elaborate upgrade path. |
I'm tentatively in favor of this as well. I'm mildly concerned about silent breakage of existing, but I don't have any good ideas for how to fix that without causing more trouble than it's worth, unless we wanted to do something trivial like swap the order of the parameters (thus forcing all clients to update their code, except the clients may not realize the semantics changed). |
So, it seems there are roughly three way to possibly handle the migration:
|
Thanks for laying those options out! I think we probably lack the time to do (2) before the beta. It seems like (3) could be a pretty reasonable option, though. In particular, we could remove the trait altogether during the beta cycle, meaning that by 1.0 we'd have a clean API. @alexcrichton Thoughts on that migration strategy? |
We've already got quite the hefty amount of deprecated code in the standard library, so I'd still be voting for the cold-turkey approach, but option (3) does indeed sound plausible to me! |
While this is a late-breaking change, there's broad agreement that it removes a potential footgun. We've decided to move forward, and to change the semantics in place (together with a very loud PSA that this is happening as part of the beta release). Thanks for the RFC! |
This commit is an implementation of [RFC 979][rfc] which changes the meaning of the count parameter to the `splitn` function on strings and slices. The parameter now means the number of items that are returned from the iterator, not the number of splits that are made. [rfc]: rust-lang/rfcs#979 Closes rust-lang#23911 [breaking-change]
This commit is an implementation of [RFC 979][rfc] which changes the meaning of the count parameter to the `splitn` function on strings and slices. The parameter now means the number of items that are returned from the iterator, not the number of splits that are made. [rfc]: rust-lang/rfcs#979 Closes rust-lang#23911 [breaking-change]
Rendered