Clarification: if I don’t export a “pirated” function/type, is that ok? An example: I’m building a package to do stuff with temperature, and using Unitful all over the place. But I want to give users the option of just calling all of the functions that take temperatures with numbers instead.
Can I do:
import Base.convert
convert(::Type{Temperature}, x::Real) = # something that turns it into temperature
(Note: Temperature isn’t actually the real type, but I’m on mobile so forgive me please)
I know I could explicitly define extra methods that take numbers as arguments, but that seems needlessly verbose. If I don’t re-export convert, it won’t actually contaminate other people’s code right?
No it’s not. See my example above for how this still (secretly) effects other codes.
Base.convert is a single function. As long as one library (Base) reexports it, it exists out there in the wild. You mutated it by adding a method. The one out there in the REPL is now mutated. That’s why type-piracy is so bad.
method piracy. You have not extended a function you don’t own on types that you don’t own. Rather you’ve overwritten an existing method in Base. (or at least stolen an existing dispatch). You have commandeered something that is already in use. It’s obviously a semi-insane thing to do if you expect anyone else to use your package.
On the other hand, for one of the scenarios mentioned above, I prefer a term that Tony Kelman used: type squatting. It’s more evocative of the problem. For instance:
If the package containing this code becomes widely used, then I’ve prevented julia, ie Base and the standard library, from extending its own function on its own types. I’m occupying something that was not being used. And evicting me could be difficult when that something needs to be used.
But, type squatting also causes an immediate problem with existing code. Namely, it may prevent an exception from being thrown as soon as possible after a function receives unsupported input data.