> The orphan rules are definitely necessary for coherence: ... and there would have to be some (likely unwieldy) mechanism to resolve that.
I think Julia, D, Nim, and others show its possible and generally easy to work with open ended type systems. I think Haskell does as well?
Though yes those come at the cost of possible conflict or user confusion, which is why I consider it a philosophical decision. It matches with the decision to not allow user code to use trait specializations in stable despite the stdlib having it.
Imports generally seem fine for controlling what gets used. Want a trait impl, import it into a module. Cargo crate features might also be a route to enforce package level decisions.
> And, of course, if you need an object to implement a trait you don't own, you can define a newtype wrapper over it, but that can also be difficult to work with sometimes.
Unfortunately that means you can't define 'default' or 'clone' traits for a type. That prevents you from using derives on your newtypes as well. That means manually implementing clone, or serde which is a PITA.
> Perhaps this situation could be improved by one of the "crate-local impl" proposals that have been floating around.
At least that'd make it somewhat easier to work with. It'd still not let end users / programmers to mix and match types and traits from different libraries without a lot of unnecessary work.