In this context, I think the right way to think about it is “type piracy is just loading code in the wrong order.” While it should generally be avoided, there are legitimate cases for this. The classic case is
ColorVectorSpace, which provides operations on colors that are “wrong” from the standpoint of exact colorimetry but which are nevertheless widely used in the image-processing world. Because the “purists” rightfully objected to them being in the same package as the non-offensive definitions and methods, we split them into two packages.
There are other cases of internal piracy. For example,consider a package that defines some useful types and methods, for which there’s a simple implementation of an algorithm and a vastly more optimal one that also introduces huge, often-undesirable dependencies. The package could define the simple implementation to be used by default, and put the more sophisticated version under a
@require. In that case it’s not technically piracy because it’s all in the same package, but it does mean that you might end up redefining internal methods depending on what other modules are loaded.
When you think about it as a question of “what order does code get loaded in?” it makes it a purely pragmatic (as opposed to moral high horse ) problem. I don’t think the answer is to erect all sorts of barriers that prevent people from getting their work done. The answer is (1) to develop tools that allow one to detect and diagnose problems (“what’s causing my slow compilation?”) and (2) design packages so that load-ordering problems crop up extremely rarely. When we agree that there are reasons for wonky ordering, we just accept that as a cost of getting those other things we want. If people just can’t agree on a common set of goals, then we have multiple packages optimized for different use cases.