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.:”?
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.
For anyone looking for a complete example, here’s an example showing the full syntax.
mutable struct MyStruct
df::DataFrame
end
function Base.:(==)(left:MyStruct, right:MyStruct)
return left.df == right.df
end
Someone already mentioned something about this, but perhaps useful to add something.
The alternative syntax for the function might have been this:
function Base.==(left, right)
...
end
But it isn’t, and this doesn’t work.
Remember that :(thing) is equivalent (approximately) to
quote
thing
end
This is related to metaprogramming, or at least disambiguating between writing something which is supposed to be interpreted in a metaprogramming context. (Sorry, this isn’t really a very good explanation.) But it’s perhaps useful to show something…
julia> Base.:(==)
== (generic function with 223 methods)
julia> typeof(Base.:(==))
typeof(==) (singleton type of function ==, subtype of Function)
julia> Base.==
^C
julia> Base.unique
unique (generic function with 7 methods)
julia> typeof(Base.unique)
typeof(unique) (singleton type of function unique, subtype of Function)
julia> typeof(Base.:(unique))
typeof(unique) (singleton type of function unique, subtype of Function)
Sorry I can’t say more about this, or provide a more clear or detailed explaination. Base.== seems to be interpreted as something a bit different to Base.functionName, such as Base.unique.