I would like to require a feature similar to specialization, but simpler and local. I expect this has probably been asked for before, by I couldn't find the keywords to find any posts.
It would be really nice to be able to ask a generic type if implements a trait without having to go through all of the trouble of making multiple definitions. My recommendation is:
fn operate<T>(x: &T) {
implcheck T:Display {
println!("{} was operated on.", x);
}
else {
println!("Input was operated on.");
}
}
During type checking, any T
within an implcheck T:A+B+C {}
block is assumed to implement A+B+C
. Then during monomorphization, if the type T
is implements the traits then the block is included, otherwise if the else block is present that is included, otherwise it is just skipped.
Although this could be done with specialization, it would be really hard on the developer. Specialization requires a ton of boiler plate. The dev has to make a new impl and a new function definition, for something that could be as easy as "hey, if this value can be printed, then print it".
Further, if there are x generics checking y traits on each of them, that requires an exponential number of boiler plate definitions: (y+1)^x. For example something like this:
fn print_triple<A, B, C>(x : &(A, B, C)) {
implcheck A:Display {
println!("A: {}", A);
}
else implcheck A:Debug {
println!("A: {:?}", A);
}
else {
println!("A: not printable");
}
implcheck B:Display {
println!("B: {}", B);
}
else implcheck B:Debug {
println!("B: {:?}", B);
}
else {
println!("B: not printable");
}
implcheck C:Display {
println!("C: {}", C);
}
else implcheck C:Debug {
println!("C: {:?}", C);
}
else {
println!("C: not printable");
}
}
To do that with specialization, it would require 27 new definitions and impl blocks.
Also, implcheck is local to the function, it doesn't have to worry about all the problems of crates conflicting on definitions and such. I expect it would be a much easier safe zero cost abstraction to implement while specialization is still being worked out.