I think you are forgetting something important: complexity has to live somewhere.
Typically “simple and obvious” features are, in reality, harder to implement than features which look, superficially, more complex.
What you are asking for is, essentially, if constexpr from C++.
And if constexpr is, of course, harder to properly design and implement than specialization.
In fact if constexpr is built on top of machinery designed for template specialization support. And it was only added in C++17 in spite of the fact that template specialization was in C++98 already (although it took years to iron out bugs in the implementation).
Note that if constexpr is, actually, a minor complication over the specialization, the main complexity lies in the specialization machinery. But I don't think anyone would seriously consider it till specialization issues would be ironed out one way or another.
It may not be obvious to you just why your simple idea is quite complicated. But consider something like this:
fn do_something<X>(x: &mut X) {
let mut log;
if X impl std::fmt::Debug {
log = fmt!("{:?}", x);
}
transform(x);
if X impl std::fmt::Debug {
eprintln!("transformed {} to {:?}", log, x);
}
}
Is this valid code or not? What about this:
fn do_something<X>(x: &mut X) {
let mut log;
if X impl std::fmt::Debug {
log = fmt!("{:?}", x);
} else {
log = 42;
}
transform(x);
if X impl std::fmt::Debug {
eprintln!("transformed {} to {:?}", log, x);
}
}
What would happen if you are dozen of checks? To understand if your code is valid or not without exploring all the possibilities (which would lead to exponential compilation times because of combinatorial explosion) you would need some quite complicated machinery.
Thankfully it's pretty similar to what specialization already have to do and would, probably, be able to reuse some of the same machinery, but… such feature is, most definitely, harder to properly define and implement than specialization.
But sure, it's much easier to use. if constexpr
made metaprogramming much more popular in C++ world. Because it become easier to implement simple things. But there are still a lot of issues related to it in the major C++ compilers.