`x - y` is not `x + (-y)`?

In some places I have found that in computer algebra, x - y can be defined as x + (-y). E.g. in Cohen’s Computer Algebra and Symbolic Computation: Mathematical Methods (page 51)

However this is not a rule for Julia types:

struct CustomNumber{T}
    data::T
end

Base.:+(x::CustomNumber, y::CustomNumber) = CustomNumber(x.data + y.data)
Base.:-(x::CustomNumber) = CustomNumber(-x.data)
julia> CustomNumber(1) - CustomNumber(2)
ERROR: MethodError: no method matching -(::CustomNumber{Int64}, ::CustomNumber{Int64})

Of course, I can define the subtraction myself using that definition:

Base.:-(x::CustomNumber, y::CustomNumber) = x + (-y)

My question is whether there is some reason for not making that the fallback subtraction method in Base.

2 Likes

That’s a good question. One might audit how often binary subtraction is defined using unary minus in existing code. If it’s used a lot, then it might be a good idea to make it a fallback. But, if it is not used much now, then it would be better to leave it undefined. People might forget to implement an efficient method if the fallback “just works” without thinking about it.

Similar issues arise in LinearAlgebra.

3 Likes

Good point. I see: Base.:-(x, y) = x + (-y) needs to allocate the intermediate result of -y, so usually it may be better to write an explicit subtraction method. Such a fallback might come in handy for complicated types, but in such a case the penalty of allocating -y would probably be greater, so the previous argument would be stronger.

1 Like