Unused traits

“Recently” Bjarne Stroustrup has said that when you use C++ concepts you should’t strive to use the minimal concepts that allow a templated function to compile, and instead you should use a coherent and organic concept that could include more than what you scrictly need. Otherwise you risk restricting too much the future implementations of your function, because a different algorithm could need a slightly different group of Concepts.

While Rust doesn’t have C++ concepts, I think those words of Stroustrup could be good for Rust too. Yet, sometimes I prefer to not over-constrain a generic function in Rust, so I’d like it to not use useless traits, like here where Debug is not used by the function:

fn quicksort<T: Copy + Ord + Debug>(a: &mut [T]) {
    if a.len() < 2 { return; }
    let pivot = a[a.len() / 2];

    let (mut i, mut j) = (0, a.len() - 1);
    loop {
        while a[i] < pivot { i += 1; }
        while a[j] > pivot { j -= 1; }
        if i >= j { break; }
        a.swap(i, j);
        i += 1;
        j -= 1;

    quicksort(&mut a[.. i]);
    quicksort(&mut a[i ..]);

“Recently” some HashMap functions have being modified to remove unnecessary Debug constraints ( https://github.com/rust-lang/rust/issues/41924 ), like here:

impl<'a, K: Debug, V: Debug> fmt::Debug for Keys<'a, K, V> {

So is it possible and a good idea to add a warning (or a lint for Clippy) that spots unnecessary trait constraints in generic functions?

1 Like

http://www.stroustrup.com/good_concepts.pdf is a good read on this (might be what you’re referring to @leonardo).

That's the paper I have read, thank you. Bjarne says:

Thus, the ideal is not “minimal requirements” but “requirements expressed in terms of fundamental and complete concepts.” This puts a burden on the designers of types (to match concepts), but that leads to better types and to more flexible code

Interestingly, it seems part of his argument stems from C++'s duck typing:

To be more realistic, people sometimes get into trouble defining something like this:

template<typename T>
concept bool Addable = requires(T a, T b) { { a+b } -> T; } ;

They are then often surprised to find that std::string is Addable (std::string provides a +, but that + concatenates, rather than adding). Addable is not a suitable concept for general use, it does not represent a fundamental user-level concept. If Addable, why not Subtractable? (std::string is not Subtractable, but int* is). Surprises are common for “simple, single property concepts.” Instead, define something like Number: [...]

And I'd continue that thought, but I'm also getting some mighty wicked deja vu right now. Have I... like, have I quoted this exact block of text before or something?

...nah. Must be my imagination.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.