I was reading up on automatic differentiation, and I noticed something weird about extending operators. I opened up the REPL and ran a couple of copied lines:

julia> struct Dual{T<:Real} <: Real

x::T

ϵ::T

endjulia> a::Dual + b::Dual = Dual(a.x + b.x, a.ϵ + b.ϵ)

- (generic function with 1 method)

Wait a minute, I wasn’t supposed to be able to extend an existing operator just like that. And addition (+) is definitely not 1 method. I try adding two integers, and it looks like I’ve overwritten the operator in a bad way:

julia> 3+5

ERROR: MethodError: no method matching +(::Int64, ::Int64)

You may have intended to import Base.:+

Stacktrace:

[1] top-level scope at REPL[3]:1

I close and reopen the REPL: fresh start. I check the + operator first thing before running the copied lines. Now Julia throws the error I expected when extending operators without explicitly using Base, and I actually do add 1 method to Base.:+ when I do it right:

julia> +

- (generic function with 166 methods)
julia> struct Dual{T<:Real} <: Real

x::T

ϵ::T

endjulia> a::Dual + b::Dual = Dual(a.x + b.x, a.ϵ + b.ϵ)

ERROR: error in method definition: function Base.+ must be explicitly imported to be extended

Stacktrace:

[1] top-level scope at none:0

[2] top-level scope at REPL[2]:1julia> Base.:+(a::Dual, b::Dual) = Dual(a.x + b.x, a.ϵ + b.ϵ)

julia> +

- (generic function with 167 methods)

Of course, since I didn’t check the subtraction (-) operator, the weird overwriting still happens for it.

julia> a::Dual - b::Dual = Dual(a.x - b.x, a.ϵ - b.ϵ)

- (generic function with 1 method)

What exactly is going on here? Is there a way I can make Julia “check” all the operators so I don’t overwrite an operator in a session and have to start over?