In the style guide, it talks about type piracy [1], the practice of extending or redefining methods on types you didn’t define. We’ve been told in the past not to do this, especially with methods and types defined by Base, as it can subtly break Julia.

However, we are in a situation where we really want to do this. The issue is with the Julia definition of the functions exp, log, inv, sqrt, sin, cos, tan (and other trig functions) and also det (for unrelated reasons).

We are writing an abstract algebra package which defines generic power series over any ring. In order for such power series functions to work, we must define all the functions above for the ring over which the power series are defined. This is ordinarily not a problem because we are defining them for types that we have defined.

One significant problem comes if we want to do power series over Julia types belonging to Integer or Rational. Here Julia defaults to the numerical standard of returning the result in the archimedean completion, instead of returning values in the original ring itself, as an algebraist would (if an algebraist wanted the value over a completion, they would specify which completion!). This implies that one simply cannot define power series over Julia Integer or Rational types in a way that is useful to algebraists.

However, there is a solution to this. Within our module (Nemo), we can define all these functions ourselves, with the usual algebraists definition, without first importing them from Base. Anyone who uses our module will have to disambiguate, but this seems to be a small price to pay. Nothing can break, as Julia itself does not use Nemo.

But we want to check with the community whether this is acceptable, or whether it would be considered type piracy? Just to be clear, we are asking whether we can define Nemo.exp, Nemo.inv, Nemo.sqrt, Nemo.det, on Julia Integer and Rational types (without importing from Base of course).

(Aside: we have long had a similar issue with / for division of integers, but we’ve worked around this by defining a function divexact, which we’ve gotten used to over time. It seems there is no similar workaround for /, as operators are handled separately. It wouldn’t be practical for anyone to have to disambiguate the use of operators. It wasn’t such a big deal, since we had to define numerous kinds of division anyway: Euclidean division, exact division, creation of elements in the fraction field, etc. The only thing it really ruins is copy and pasting of pretty printed output back into the REPL.)

[1] https://docs.julialang.org/en/stable/manual/style-guide.html#Avoid-type-piracy-1