How to overload the ==?

I defined the Base.isequal function, but it do not work.

               _       
   _       _ _(_)_     |  A fresh approach to technical computing            
  (_)     | (_) (_)    |  Documentation: https://docs.julialang.org          
   _ _   _| |_  __ _   |  Type "?help" for help.                             
  | | | | | | |/ _` |  |                      
  | | |_| | | | (_| |  |  Version 0.5.2 (2017-05-06 16:34 UTC)               
 _/ |\__'_|_|_|\__'_|  |  Official http://julialang.org/ release             
|__/                   |  x86_64-pc-linux-gnu 

julia> type Foo foo::Int end                  

julia> type Bar bar::Float64 end              

julia> f = Foo(4)      
Foo(4)                 

julia> b = Bar(4.0)    
Bar(4.0)               

julia> function Base.isequal(a::Foo, b::Bar)  
           Float64(a.foo) == b.bar            
       end             

julia> isequal(f, b)   
true                   

julia> f == b          
false                  

isequal falls back to ==

julia> @code_lowered isequal(f, b)
CodeInfo(:(begin 
        nothing
        return x == y
    end))

you can do Base.:(==)(a::Foo, b::Bar) = ...

see https://docs.julialang.org/en/stable/stdlib/base/#Base.isequal-Tuple{Any,Any} for more info

1 Like

Thanks, this works.

I need to redefine Base.:(==) separately to make == work.

you likely don’t have to touch isequal at all, unless you want it to behave differently from ==.

1 Like

Hello - I realize that I am resurrecting a long dead post, but I tried to follow the documentation link … and it was dead.

I had been trying to understand this method declaration in Clang.jl, and landed on this question from a web search. Can someone explain why the function needed to have the prefix “Base.:”?

Thx

If you define an unspecified == method, what you’re actually defining is CURRENTMODULE.:(==). This is not the == used except in CURRENTMODULE or modules that explicitly import this version. If you want to affect the behavior of == in other modules, you need to modify the version of == used in those places. In most cases, this is Base.:(==).

This is to avoid method conflicts. It may not appear to make much sense for operators like ==, but it this is very important for other functions. If there was only one shared namespace, method collisions would happen and it would be very difficult to compose functionality from different modules.

@mikmoore, thanks for the reply - and forgive the obtuseness of the question (I am rather new to Julia), but why is the : necessary? From the documentation on modules, I would have figured that it would have been something like CURRENTMODULE.==, rather than CURRENTMODULE.:(==)?

I believe the :() is required for operators for syntactic reasons. Otherwise it parses Base.==(1,2) as Base .== (1,2). Then it gets upset about trying to broadcast a module Base. Even if we defined broadcasting on modules, it would then try to evaluate (Base == 1, Base == 2) which still isn’t what you were trying to do.

To avoid this syntax ambiguity, it’s necessary to use MODULE.:(==) for operators.

Since it’s very tedious to specify modules for operators, it’s not very common to make module-local versions. Rather, people mostly add methods to the Base versions (e.g., Base.:(==)) instead. Just be careful to only define external module (like Base) functions on types you have created in the current module you’re working in, or else you can run into the problems of type piracy.

2 Likes