Your second paragraph basically lists the difficulties. It's definitely a compromise.
https://github.com/rust-lang/rfcs/pull/105#issuecomment-6410...
?
Type inference does make such things easy inside function bodies, but there are a lot of functions so it's not a complete solution.
Even some of the uncomposed iterator signatures are uncomfortable. An example:
fn partition<B, F>(self, mut f: F) -> (B, B) where
Self: Sized,
B: Default + Extend<Self::Item>,
F: FnMut(&Self::Item) -> bool
D gives you Range partition(alias predicate, SwapStrategy ss = SwapStrategy.unstable, Range)(Range r)
if ((ss == SwapStrategy.stable && isRandomAccessRange!(Range))
|| (ss != SwapStrategy.stable && isForwardRange!(Range)))
which, if changed to only support stable partitions (like Rust), would be Range partition(alias predicate, Range)(Range r)
if (isRandomAccessRange!(Range))
Note that I'm _not_ saying D's solution is better. I'm saying I find it more comfortable.