I would like to create a next! function for a custom type, but avoid conflict with other modules that might define next! as well. A very small example:
module NextTest
export Numb, next!
mutable struct Numb
val::Int
function Numb()
new(0)
end
end
function next!(n::Numb)
n.val += 1
return n.val
end
end # module NextTest
I start using it like this:
julia> using NextTest
julia> n = Numb()
Numb(0)
julia> next!(n)
1
julia> next!(n)
2
And now I want to use ProgressMeter which also defines next! and I get this:
julia> using ProgressMeter
WARNING: using ProgressMeter.next! in module Main conflicts with an existing identifier.
I would have thought that multiple dispatch would allow the two next! functions to easily co-exist since they operate on different types.
I realize that I could add this line to my module’s definition:
import ProgressMeter: next!
and the problem goes away. But there may be other modules that want to define next! and it’s not clear why (say) ProgressMeter should be the “owner” of this function name.
None of the packages “own” the function. If you are extending the function from ProgressMeter it is natural to import it in your module. If you are not extending it, then the two next functions are different functions, and having to use them with the explicit module name is necessary to avoid conflicts.
Note that, of course, you can define any (non-base) function name inside your module, acting on types that you do not own. If that automatically was considered adding methods to functions with common names it would be impossible to prevent type piracy.
Ps. The specific problem is avoided by using import ProgressMeter instead of using, such that you do not bring it’s functions to your name space.
Thanks. I just figured that since “my” next! is defined for different types than other functions named next! , that would be suffice to disambiguate and I would not have to write My.next! vs Their.next!.
Do you actually need to use ProgressMeter.next! in your code? If, for example, you only need @showprogress, then I would do the following:
julia> next!() = 1
next! (generic function with 1 method)
julia> using ProgressMeter: @showprogress
Note that this does not generate a warning. If you do need ProgressMeter.next!, then as @lmiq mentioned, you can do import ProgressMeter and then write ProgressMeter.next! whenever you need the next! from ProgressMeter. Note that when you do this you won’t need to prefix your own version of next!.
Also note that you can combine import and using, so that you can use other names from ProgressMeter without prefixing them:
julia> next!() = 1
next! (generic function with 1 method)
julia> using ProgressMeter: @showprogress
julia> import ProgressMeter
julia> ProgressMeter.next! === next!
false
Thanks. I don’t actually need ProgressMeter in the case I’m considering. But sometimes I would use it together with my own project. In any case, I can use the long-form names in the instances when I do use both. I was just curious about why this was even necessary since the two next! functions take different types of arguments. OK to let this go. Thanks so much!
There is a very long thread on Discourse about this very subject, but I don’t have a link handy. Basically, the philosophy is that a generic function should have a generic definition that applies to all its methods. In this case, ProgressMeter.next! and your next! have very different meanings, so they should not be methods of the same generic function.