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 upFunction specialization #7059
Comments
This comment has been minimized.
This comment has been minimized.
|
Define "most specialized". The one with the highest number of generic bounds? Then when you refactor your code to collapse several bounds into one via trait inheritance, you've silently changed the meaning of the program. So then perhaps you could count the number of generic bounds by recursively expanding each trait into the ones it inherits from... but now fussing with traits anywhere higher in the inheritance chain can again silently change which function is selected, except arguably worse because it's action-at-a-distance. "First that matches" also doesn't work, because non-closure functions have no concept of order. Note that this program works: fn main() {
foo();
bar();
fn bar() {
foo();
println("bar");
}
fn foo() {
println("foo");
}
}I'm not necessarily opposed to this idea, but there needs to be a concrete proposal that considers these complications. |
This comment has been minimized.
This comment has been minimized.
|
In this specific case it is quite obvious what would be the most specific trait, since Signed implies Ord, Zero, Neg and more. I would consider the following rules something to start discussing,
|
This comment has been minimized.
This comment has been minimized.
|
This is basically proposing something like the "most specific instance" rule in GHC when you pass in the |
This comment has been minimized.
This comment has been minimized.
|
I like the idea of specializing functions, but it seems like there are other ways to do it. Most of the time you just want a version for |
This comment has been minimized.
This comment has been minimized.
|
@thestinger Yeah, that is essentially the same thing as I want, just with different syntax. |
This comment has been minimized.
This comment has been minimized.
|
In Haskell the reason it's impossible to have complements of constraints (or more generally to branch on the "otherwise" case in any way) is the open-world assumption. There's no way to rule out the possibility of an instance ( What this ticket is asking for is actually more than that, because it's also asking for a kind of implicit C++-style overloading on functions. We already have implicit overloading for the Considering only the trait complements / boolean trait expressions half of it, obviously
Drawbacks:
|
This comment has been minimized.
This comment has been minimized.
|
@bjz has a proposal for overlapping impl precedence; reproduced here for posterity:
I think the arguments about overlapping instances in Haskell don't fully apply because Rust doesn't have the (entire) open world assumption like Haskell. In particular, I believe that, for any "pattern" that overlaps, Rust can see all of the possibilities at once, because at least one of the trait or type have to be defined in the current crate. E.g. you can't write // crate1.rs
trait Foo {}
impl<T,U> Foo for (T,U) {}
// crate2.rs
impl<T> Foo for (T, int) {}
// crate3.rs
impl<U> Foo for (float, U) {}and so you can never have the situation where importing |
This comment has been minimized.
This comment has been minimized.
|
My own specific desire with it is very simple, to do with augmented assignment (#5992). Given a trait definition like this: pub trait AddAssign<RHS> {
#[inline]
fn add_assign(&mut self, rhs: &RHS);
}What I really want is simply this: impl<LHS: Add<RHS, LHS>, RHS> AddAssign<RHS> for LHS {
fn add_assign(&mut self, rhs: &RHS) {
*self = *self + *rhs;
}
}This has the effect of making A couple of ideas of mine:
|
This comment has been minimized.
This comment has been minimized.
|
@huonw, good point. I believe you could still have that situation when importing different modules from the same crate? But maybe that's no longer concern-worthy? The other criticism levelled in the SO answer still holds: if upstream adds a new, more specific impl, that could silently change the behaviour of downstream code. It seems like a good idea to preserve the property that merely adding something new can't change the behaviour of something that already exists. I think this will be a problem with any system where you have 'one impl to rule them all' that you can override on a per-case basis. Would it be so burdensome to have to write an empty (Apropos, GHC has a feature called DefaultSignatures. Basically what that does is it lets you write a default implementation for a method with a more specific signature than the method itself (e.g. additional trait bounds), and the default is generated only if the more specific signature is satisfied. But you still have to declare the FWIW I think a system with explicitly negated traits and strict-but-taking-bounds-into-consideration overlap checking would also allow similar problems:
Now if you add an @chris-morgan, two questions:
Your I believe Rust used to have explicit import/export of |
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
|
@chris-morgan, wrt
that's exactly what GHC's
if you try to translate that to Rust:
What goes in Anyways, the point is not to bikeshed syntax, I originally wanted to translate it into Rust to help explain what it does. |
This comment has been minimized.
This comment has been minimized.
|
FWIW, both @thestinger and I have also found uses for implementing a default method when |
chris-morgan
referenced this issue
Aug 7, 2013
Closed
Proposal: Implement assignment operator overloads #5992
chris-morgan
added a commit
to chris-morgan/rust
that referenced
this issue
Feb 11, 2014
flaper87
added a commit
to flaper87/rust
that referenced
this issue
Feb 11, 2014
chris-morgan
referenced this issue
Mar 23, 2014
Closed
RFC for adding an `Iterable` trait family #17
This comment has been minimized.
This comment has been minimized.
|
This can & should be converted into a new-style RFC. |
SimonSapin
referenced this issue
Apr 29, 2014
Closed
RFC: Add size hint methods on Reader and Writer #46
This comment has been minimized.
This comment has been minimized.
|
I've been playing with vectors, matrices and BLAS, and I've encounter this issue repeatedly. See this gist for an example. I've independently reach the solutions formulated by @chris-morgan in his first comment. Namely:
|
chris-morgan
added a commit
to chris-morgan/rust
that referenced
this issue
Jun 1, 2014
chris-morgan
added a commit
to chris-morgan/rust
that referenced
this issue
Jun 1, 2014
This comment has been minimized.
This comment has been minimized.
|
This issue has been moved to the RFCs repo: rust-lang/rfcs#290 |
jensnockert commentedJun 11, 2013
Code like this should work, preferably picking the most specialized function (and/or just picking a random one, or the first that matches &c. or just throw a warning)