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

binary_search methods should use Borrow #32822

Closed
osa1 opened this issue Apr 8, 2016 · 12 comments
Closed

binary_search methods should use Borrow #32822

osa1 opened this issue Apr 8, 2016 · 12 comments
Labels
E-help-wanted Call for participation: Help is requested to fix this issue. P-medium Medium priority T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@osa1
Copy link
Contributor

osa1 commented Apr 8, 2016

binary_search() takes a reference of the element instead of using Borrow instances. This is causing problems:

  1. &String doesn't make any sense. I should be able to just use &s where s is a String to search in a Vec<String>.
  2. Current API sometimes causes redundant allocations (e.g. when I have a &str at hand, I need to allocate a String)
  3. API is inconsistent in that some other containers use Borrow for this purpose. E.g. HashMap. As a guideline, I think lookup functions of containers should just use Borrow always.
@huonw huonw added the A-libs label Apr 8, 2016
@huonw
Copy link
Member

huonw commented Apr 8, 2016

&String doesn't make any sense. I should be able to just use &s where s is a String to search in a Vec.

Hm, could you clarify this point? &String makes perfect sense, and using &s works fine. The following code compiles and runs:

fn main() {
    let v = vec!["abc".to_string(), "def".to_string()];

    let s: String = "def".to_string();
    println!("{:?}", v.binary_search(&s));
}

Also, it's worth noting that binary_search_by exists, and means that there's no fundamental issue with the functionality, it just requires a little more typing:

fn main() {
    let v = vec!["abc".to_string(), "def".to_string()];

    let s: &str = "def";
    println!("{:?}", v.binary_search_by(|x| x.as_str().cmp(s)));
}

(Don't get me wrong, it would be nicer if Borrow worked with the sugary version.)

@huonw huonw added I-nominated T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Apr 8, 2016
@huonw
Copy link
Member

huonw commented Apr 8, 2016

Nominating for libs team discussion: we should be able to relax the parameter here, but seems worth discussing. (It is formally a minor change, and I suspect that not many people are relying on this function for type inference.)

@osa1
Copy link
Contributor Author

osa1 commented Apr 8, 2016

Hm, could you clarify this point? &String makes perfect sense, and using &s works fine.

I didn't mean it doesn't work or anything like that. I just meant that if I want to pass a read-only reference to a string I'd use &str instead of &String, unless the string will be modified, in which case I'd use &mut String. I don't see any advantage of &String over &str, but it has disadvantages, like, if you have &str you need an allocation, but you can easily get a &str from String without any allocations.

@huonw
Copy link
Member

huonw commented Apr 8, 2016

Ah, ok, thanks for scaling back the hyperbole ;) You are correct that &str is strictly more flexible than &String, and the only reason for &String to occur is generic functionality e.g. this example (though obviously Borrow changes that), or calling clone, etc.

@alexcrichton
Copy link
Member

The libs team discussed this issue during triage today and the conclusion was that we probably want to do this as it basically means "more code works" at only the slight cost of readability in the docs.

Before this is done, however, we'd like to see a bit of a small survey of the rest of the standard library that this pattern could also apply. For example the contains method on slices could likely also receive this treatment, and there are perhaps other applicable locations for this as well.

@alexcrichton alexcrichton added P-medium Medium priority and removed I-nominated labels May 4, 2016
@brson brson added the E-help-wanted Call for participation: Help is requested to fix this issue. label Nov 3, 2016
@brson
Copy link
Contributor

brson commented Nov 3, 2016

All we need to do here is the survey @alexcrichton suggested, then make the patch.

@christophebiocca
Copy link
Contributor

I just looked over the standard library and the following are candidates for this change:

Slice

Clone

Ord, PartialOrd and PartialEq

The cmp, partial_cmp, eq and ne methods could use this, but as they are public traits this would not (?) be backwards compatible. Also it looks like most of the possible pairs of &str and friends have already been added to all traits except Eq (which has no flexibility for RHS).

LinkedList

VecDequeue

@christophebiocca
Copy link
Contributor

Turns out clone_from has the same backcompat issues, as implementers can choose to override the default implementation from the trait.

alexcrichton added a commit to alexcrichton/rust that referenced this issue Dec 20, 2016
…efactor, r=alexcrichton

Use Borrow for binary_search and contains methods in the standard library

Fixes all standard library methods in rust-lang#32822 that can be fixed without backwards compatibility issues.
@alexcrichton
Copy link
Member

Added in #37761, so closing.

@Kimundi
Copy link
Member

Kimundi commented Mar 16, 2017

#37761 Seem to have only added the change to core, not to std. Was this intentional?

@christophebiocca
Copy link
Contributor

libcollections does not have the change and that was an oversight on my part. Is that what you mean?

@Kimundi
Copy link
Member

Kimundi commented Mar 17, 2017

Yeah, exactly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
E-help-wanted Call for participation: Help is requested to fix this issue. P-medium Medium priority T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants