Defining my own `next!` but avoiding confict

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.

Is there another approach that would be better?

2 Likes

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!

Sort off, what if you wanted your code to error if your next was called with the wrong type?

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.

EDIT: Found the link:

2 Likes