Closed wbhart closed 3 years ago
The following example of @martinra shows why arithmetic operations should also be careful to not allow aliasing of any part of their inputs with their output:
R,x = LaurentSeriesRing(QQ,20,"x")
a = sum(n*x^n for n in 1:17)
b = 83 + 43*x^10 + O(x^20)
c = a + b
ccp = deepcopy(c)
addeq!(a,b)
c-a
c-ccp
Here, if c aliases some coefficients with a or b after c = a + b then c will be modified by the call to addeq!(a, b).
This is now documented in devel docs.
We decided:
Note that matrices are handled slightly differently from other objects. Currently matrices are viewed as containers which can contain elements that may alias one another. Other objects, e.g. polynomials, series, etc., are constructed from objects that do not alias one another, even in part.
standard unsafe operators, addeq!, mul!, addmul!, zero!, add!, etc, are allowed to mutate their outputs iff the output is entirely under the control of the caller, i.e. it was created for the purpose of accumulation, but otherwise must not modify any inputs or outputs
all arithmetic functions (unary -, +, -, *, ^, and possibly div, divrem, mod, divexact and gcd) must return new objects and cannot return one of their inputs
all other functions are allowed to return their inputs as outputs
matrix functions with an exclamation mark should not mutate the objects that occur as entries of the output matrix, though should be allowed to arbitrarily replace/swap the entries that appear in the matrix. In other words, these functions should be interpreted as inplace operations, rather than operations that are allowed to mutate the actual entries themselves.
R(a) where R is the parent of a, always just returns a and not a copy
setcoeff! and setindex! and getcoeff and getindex should not make copies (Flint matrices and polynomials effectively always copy on the way in and out, but this is accepted and even required behaviour). Note that this implies that setcoeff! should not be passed an element that aliases another somewhere else, even in part
Constructors for polynomials, series and similar ring element objects (that are not matrices) that take an array as input, must ensure that the coefficients being placed into the object do not alias, even in part.
{say something about whether zero creates a fresh object or not}