Even more clarification on Type piracy

# Module A
abstract type Structs end
general(obj::Structs) = "This is the " * name(obj)
name(obj::Structs) = getfield(obj, :general)
# Module B
mutable struct MyStruct <: Structs
    general::String
    nickname::String
end
A.name(obj::MyStruct) = getfield(obj, :nickname)

I might assume knowing module A that

a = MyStruct("A", "B")
if general(a) == "This is the A"
    println("Expected")
end

but I got "This is the B". Imagine rather than the silly example, I am defining a <: StatsBase.RegressionModel and made it such that the r2 for my struct gives a different definition. If anyone uses the general API and calls r2 on my package models it will give the wrong answer. That can happen a lot in pipelines such as DataFrames, StatsBase, StatsModels, and a package. It might not break a package if I only use PackageA and PackageB, but as soon as there is a PackageC that interacts with those it could break it.

Type piracy could also occur when a package defines a method as x + y and you apply the method to your struct as 2 * x + y. You are basically, high-jacking the method for something else and breaking the API. Once there is a heretic, the API is no longer credible and development can’t use the API to guarantee that it will work with the <: ModuleA.AbstractTypeA. At least that is the definition I rely on for piracy (it might break interaction between packages rather than limit it to between two packages).

@stevengj, I remember you telling that piracy occurs when both you don’t own the method or struct (if not mistaken).
“”"
It is type piracy (this is a technical term in Julia-verse), because this hypothetical package would be extending a function step defined in another package, with the new method acting only on types defined in another package (AbstractVector and Date).
“”“”
So type piracy might be less broadly defined than what I described above.