My firm belief is that it is nonsense for a crate to require you to
use a trait in order to call methods on types defined by that crate, when those methods feel like they should be part of the type.
I can think of plenty of examples of what I consider to be bad:
- You can do many things out of the box with a
stack::ArrayVec, but if you want to
pushto it, you need to import
mpi::collective::Root. Not only is this highly important functionality hidden under some unusually-named trait in some arbitrarily-named submodule, but it’s only implemented for one type. Why aren’t these simply inherent methods on that type!?
- You must import
error_chain::ChainedErrorto call the
.chain_errmethod on types generated by
error_chain. This is a particularly nasty example because you usually want to call this on error types generated in other crates, and those other crates might depend on different versions of
These have a number of issues:
- Having to import extra traits to use core functionality of a type is silly. If you later refactor the code that calls the method and move it to another module, you have to move that
- There is a disconnect between the name you must import versus the method name you are trying to call. That’s more things for the user to remember. (the same issue with publicly exposing an overly-nested hierarchy)
- Most of these traits are things I wouldn’t want to import even if I wanted to use them generically. (I’d rather use them as crate-qualified names). But if they are to be used for their methods, they absolutely must be imported. This leads to a messy namespace.
- If there’s static methods and blanket impls on uncovered
T, then it can cause ambiguities that are impossible to resolve.
In my opinion, many of these examples (with the exception of mpi::Root which ought not exist) should have inherent methods identical to the trait methods. I.e.
ArrayVec should have
fn push in addition to
Why both? Easy:
ArrayVec::pushis for people who want to use
Vector::pushis for people who want to be generic over
Now, I was asked to find examples of crates that actually do things the way I suggest. The trouble is, this is the sort of thing that, when a crate does it right, you don’t notice.
Are there popular crates that provide inherent versions of trait methods for ergonomics? Or does nobody agree with these ideals?
(note: you can’t say frunk; I added the inherent methods to that crate)