Hi,
Just a potential suggestion - more of the beginnings of an idea really... Not sure where to post this so just posting as uncategorized. Feel free to move it.
Sorry my Rust may also be a bit "rusty". I haven't written much Rust for quite some considerable period of time. I might get some things wrong here... (Hopefully not all of it...)
The following example is taken from Programming Rust 2nd Edition (O'Reilly).
fn top_ten<T: Debug + Hash + Eq>(values: &vec<T>) { ... }
In this example (and also in general), when writing a generic function the programmer must specify the traits which constrain a generic type parameter such as T
in this example.
I wonder whether this explicit information is neccessary. Could it be possible to write an implementation of the Rust compiler which figures out at compile time whether or not T implements some set of required methods?
Another way to phrase this question would be to ask Why are the explicit Traits to constrain T
required?
For example, could it be possible to write this:
fn top_ten<T>(values: &vec<T>) {
let mut h = HashMap::new();
for value in values {
// ignored code...
h.insert(value.clone()); // this function call implies that T: Hash + Eq because
// internall it will explicitly call a hashing function and an equality comparison operator ?
}
}
This doesn't require T: Debug
, but we could make it require this too by calling println!("{value:?}");
somewhere in the loop.
Actually, I don't think it is the Trait information which is important. What matters is (for example) "does T
implement a clone()
function?" My assumption is that the compiler could answer this question at compile time.
Can anyone provide any insight here? I am interested to know more about why the explicit Trait specification is required.
If you want a deeper understanding of why I am asking this, the reason is due to the following hypothesys:
- (This is my hypothesys, which may be incorrect.) If Rust did not require explicit Trait specification, then it would be easier to avoid the "type soup" which comes with writing large collections of Traits when inheritance is involved.
Similar issues arrise in C++ (and other OOP languages) whenever inheritance exists. It can be difficult to avoid writing inflexible designs which involve lots of types with complex inheritance relations. Of course, there are ways to avoid this, but it requires some careful thought/design.
I have found myself also creating type soups with Traits in Rust, hence why this question came to mind.