Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign up`sort_by` takes a comparison fn, but `min_by`/`max_by` take a "scoring" fn #15311
Comments
This comment has been minimized.
This comment has been minimized.
|
cc @aturon One possibility could be that |
thestinger
added
the
A-libs
label
Sep 19, 2014
This comment has been minimized.
This comment has been minimized.
|
Has there been any progress on this? I only recently noticed this inconsistency, and it looks like Python 2 provides both |
This comment has been minimized.
This comment has been minimized.
|
Key functions would not work well for min/max things without a total order like floats. Ideally you would use comparison based Unfortunately, currently Rust functions cannot return a closure, so creating a |
This comment has been minimized.
This comment has been minimized.
|
Scratch that, you actually CAN make a comparing-like function: #![feature(unboxed_closures)]
#![feature(core)]
use std::cmp::Ordering;
pub fn comparing<F,T,B>(f: F) -> Comparing<F> where
F: Fn(&T) -> B,
B: Ord
{
Comparing(f)
}
pub struct Comparing<F>(F);
impl<'a,'b,F,T,B> Fn<(&'a T, &'b T)> for Comparing<F> where
F: Fn(&T) -> B,
B: Ord
{
type Output = Ordering;
extern "rust-call" fn call(&self, args: (&T, &T)) -> Ordering {
self.0(args.0).cmp(&self.0(args.1))
}
}
#[derive(Debug)]
struct A(u8);
fn main() {
let mut a = [A(4), A(2), A(6), A(9)];
a.sort_by(comparing(|x: &A| x.0));
println!("{:?}", a);
}I can't get it to properly infer the parameter to the closure though. This would make it a lot more ergonomic to use a comparator based |
kmcallister
added
the
I-nominated
label
Feb 13, 2015
This comment has been minimized.
This comment has been minimized.
|
FWIW, Scala also has the |
This comment has been minimized.
This comment has been minimized.
|
1.0 beta, P-backcompat-libs, I-needs-decision. |
pnkfelix
added
P-backcompat-libs
I-needs-decision
labels
Feb 19, 2015
pnkfelix
added this to the 1.0 beta milestone
Feb 19, 2015
pnkfelix
removed
the
I-nominated
label
Feb 19, 2015
This comment has been minimized.
This comment has been minimized.
|
I'm |
This comment has been minimized.
This comment has been minimized.
|
2×3 = 6 functions isn't too bad as combinatorial explosion goes, but it still indicates that an important abstraction is missing. For example In this case the clear alternative is Haskell's |
This comment has been minimized.
This comment has been minimized.
|
It looks like |
This comment has been minimized.
This comment has been minimized.
|
@shepmaster Yes, but you can avoid that cost by using a |
This comment has been minimized.
This comment has been minimized.
|
I agree with the "less ergonomic" comment - there's yet another
Maybe if nothing else, maybe this bug can be to just rename and normalize the |
This comment has been minimized.
This comment has been minimized.
|
Yeah, i.map(|x| (x, f(x))).max_with(comparing(|(_, h)| h)).map(|(v, _)| v)looks a lot better in Haskell: map fst . maximumBy (comparing snd) $ map (\x -> (x, f x)) iAlthough the right-to-left data flow always bugged me. Naturally, this code can be made even shorter and less clear. |
This comment has been minimized.
This comment has been minimized.
|
Upon thinking more on this, I'm starting to convince myself that the scoring fn variant is not all that useful for Rust unfortunately. For example if you have a people.sort_by(|person| &person.name);Unfortunately you cannot return a reference into the argument passed into the closure, so this will not compile. This means you'll need to either call Additionally, the interaction between There is a downside, however, to not returning All this is basically leading me to:
How does that sound to others? |
This comment has been minimized.
This comment has been minimized.
|
For the min/max funcitons it is probably better to introduce a new enum {smaller, greatorOrEqual} or to return an bool. The sort_by function is not very to discover. In servo there is even a other sort function https://github.com/servo/rust-selectors/blob/master/src/quicksort.rs . I think it would be better to leave the api unstable and clean it with an rfc. |
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton You've raised some excellent points -- in particular about scoring not being as usable as one might imagine at first. I'm going to take this off the milestone; I think the triage: P-high () |
rust-highfive
added
P-medium
and removed
P-backcompat-libs
labels
Mar 24, 2015
aturon
removed this from the 1.0 beta milestone
Mar 24, 2015
aturon
removed
the
I-needs-decision
label
Mar 24, 2015
This comment has been minimized.
This comment has been minimized.
|
It would be great if |
Nemikolh
added a commit
to oil-lang/oil-rs
that referenced
this issue
Apr 18, 2015
Byron
referenced this issue
May 5, 2015
Closed
Review usage of `max_by` in `did_you_mean` implementation #99
This comment has been minimized.
This comment has been minimized.
yongqli
commented
Jun 26, 2015
|
I'd like to see this issue resolved as well. It might also make sense to implement |
This comment has been minimized.
This comment has been minimized.
|
I wouldn't mind if the function was renamed ( However, I wouldn't want to it to require Clash with |
This comment has been minimized.
This comment has been minimized.
photino
commented
Sep 13, 2015
|
I would like to see this issue resolved. Usability, clarity, and consistency is more important. It will be great to implement |
This comment has been minimized.
This comment has been minimized.
|
I do find scoring useful in practice, personally. I can see how the example "score" of |
This comment has been minimized.
This comment has been minimized.
|
We decided in #27724 to go with |
ben0x539 commentedJul 1, 2014
This is sorta inconsistent :(
fn sort_by(self, compare: |&T, &T| -> Ordering)fn max_by<B: Ord>(&mut self, f: |&A| -> B) -> Option<A>Having a comparison function is kinda more useful because then you could use
min_by/max_bywith non-totalOrdtypes more easily, but it's also a bit more effort in the easy case. I dunno. fwiw, ruby'ssort_bytakes a "scoring"-like block and haskell'ssortBytakes a comparison function.