Flexibility brings not only implementation complexification, but also doc complexification. Maybe there is a way to battle this?
impl Trait world and there was a public function
fn qqq() -> impl Mmm;
But after iterations of making it more and more advanced (while retaining backwards compatibility), it ended up like:
fn qqq<X = ResonableDefault>() -> HorribleMonster<Dread,Fear<Danger>>;
impl<T,Y> Abomination<Y> for HorribleMonster<T,Y>;
impl<T,Y> Mmm for HorribleMonster<T,Y>;
impl<T,Y> Atrocity<T> for HorribleMonster<T,Y>;
Juding just from signature of
qqq it’s not immediately obvious that the main thing and main usage of the monster is
Mmm, which was clearly communicated by
impl Mmm before.
Also type parameter
X is only for an obscure optimization majority of users won’t care about.
So for documentation (including compiler messages) purposes
qqq still wants to be cute little
fn qqq() -> impl Mmm;.
In easy mode some defaulted type parameters would be hidden and some return types be replaced with a trait (as if in
impl Trait, but in reality it’s a concrete type), maybe some methods hidden outright.
Like an boosted #[doc(hidden)]
It may be implemented as mock module with simplified structs, enums, traits, fns just for the doc, with the compiler checking that the mock module is a subset of the real module.
Or it may be just some doc attributes tuning the way which is easy content and which is advanced content.
Precedent: CMake’s “advanced” options