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?