# Functions from different modules with the same name

**URL:** <https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505>\
**Category:** General Usage\
**Tags:** pluto, namespaces\
**Created:** [May 20, 2021, 10:22am UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505 "2021-05-20T10:22:42Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![pg261](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pg261/32/24270_2.png) [@pg261](https://discourse.julialang.org/u/pg261)\
**Post date:** [May 20, 2021, 10:22am UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/1 "2021-05-20T10:22:42Z")

</div>

Hi !

I have a problem which I thought should never happen with Julia. The result is even worse when using Pluto.

I use two modules, which have a function with the same name, but taking parameters of different types. I thought that `using` them at the same time would create several methods for the same function, and that all would be good… not so.

Specifically, consider

```julia
using AbstractAlgebra # I use the permutations defined there
p= perm"(1,2,3)"
cycles(p) # this works, so far

```

So this works. But suppose that I try

```julia
using Permutations # also defines permutations,
                    # and also has a function 'cycles'
                    # so this issues a warning
q= Permutation([3,2,1])
cycles(q) # fails

```

This fails with `ERROR: MethodError: no method matching cycles(::Permutation)`. Why doesn’t the second `using` statement merely add a method to the function `cycles` ?

This seems to work routinely in other contexts, like the `*` operator having more and more methods as we import more modules. In fact, these two modules above do define `*` for their respective permutations, and all works fine.

(One guess: people write `function Base.*` or something, letting Julia know explicitly what they want to achieve. But surely this cannot be the only way to add methods to a function, this would bring many questions, that I save for later…)

When i try all this under Pluto, things are actually worse : after the second `using` statement, even the first `cycles` function is “broken” – that is, calling `cycles(p)` fails with `UndefVarError: cycles not defined`.

So weird… ideas, anyone?

thanks!  
Pierre

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [May 20, 2021, 11:16am UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/2 "2021-05-20T11:16:47Z")

</div>

Usually you should have received a WARNING, didn’t you:

```julia
julia> module A
         export f
         f(x) = 1
       end
Main.A

julia> module B
         export f
         f(x) = 2
       end
Main.B

julia> using .A, .B

julia> f(1)
WARNING: both B and A export "f"; uses of it in module Main must be qualified
ERROR: UndefVarError: f not defined

```

This is because if `A` or `B` do not explicitly use the other and _add a method_ to the function defined to the other, there is no reason to think that both functions are the same instead of just two different functions which happened to have the same name.

For that to work as different methods of the same function one of the modules should have imported the function from the other first:

```julia
julia> module A
         export f
         f(x::Float64) = 1
       end
Main.A

julia> module B
         import ..A: f
         export f
         f(x::Int) = 2
       end
Main.B

julia> using .A, .B

julia> f(1)
2

julia> f(1.0)
1

```

Then Julia would know that the two methods are methods of the same function.

If that was not done, you need to qualify the use of the functions:

```julia
julia> A.f(1)
2

julia> B.f(1)
2

```

and if you really need a convenience syntax, you can add your own methods:

```julia
julia> module A
         export f
         f(x) = 1
       end
Main.A

julia> module B
         export f
         f(x) = 2
       end
Main.B

julia> using .A, .B

julia> f(1)
WARNING: both B and A export "f"; uses of it in module Main must be qualified
ERROR: UndefVarError: f not defined
Stacktrace:
 [1] top-level scope
   @ REPL[4]:1

julia> f(x::Int) = A.f(x)
f (generic function with 1 method)

julia> f(x::Float64) = B.f(x)
f (generic function with 2 methods)

julia> f(1)
1

julia> f(1.0)
2

```

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [May 20, 2021, 11:23am UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/3 "2021-05-20T11:23:13Z")

</div>

I guess there is bound to be a problem if you have two functions with the same name and accepting the same arguments and argument types.

Does your code work if you do:

```julia
using AbstractAlgebra # I use the permutations defined there
p= perm"(1,2,3)"
AbstractAlgebra.cycles(p) # this works, so far

```

and

```julia
using Permutations # also defines permutations,
                    # and also has a function 'cycles'
                    # so this issues a warning
q= Permutation([3,2,1])
Permutations.cycles(q) # fails

```

Since Julia 1.6.0, you can also introduce aliases for `import`, so you can try:

```julia
import AbstractAlgebra as aal # I use the permutations defined there
p= aal.perm"(1,2,3)" # is `perm` a function from `AbstractAlgebra`?
aal.cycles(p) # this works, so far

```

and

```julia
import Permutations as prm # also defines permutations,
                    # and also has a function 'cycles'
                    # so this issues a warning
q= prm.Permutation([3,2,1])
prm.cycles(q) # fails

```

I’m not sure whether the Julia designers have come up with some “standards” for aliases???

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [May 20, 2021, 11:34am UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/4 "2021-05-20T11:34:37Z")

</div>

Complementing the previous answers with the specific example:

```julia
julia> using AbstractAlgebra, Permutations

julia> p = perm"(1,2,3)"
(1,2,3)

julia> cycles(p)
WARNING: both Permutations and AbstractAlgebra export "cycles"; uses of it in module Main must be qualified
ERROR: UndefVarError: cycles not defined
Stacktrace:
 [1] top-level scope

```

Does not work, use must be qualified:

```julia
julia> AbstractAlgebra.cycles(p)
Cycle Decomposition: (1,2,3)

julia> q = Permutation([3,2,1])
(1,3)(2)

julia> Permutations.cycles(q)
2-element Vector{Vector{Int64}}:
 [1, 3]
 [2]

```

And you can define your methods explicitly:

```julia
julia> cycles(p::typeof(p)) = AbstractAlgebra.cycles(p)
cycles (generic function with 1 method)

julia> cycles(q::typeof(q)) = Permutations.cycles(q)
cycles (generic function with 2 methods)

julia> cycles(p)
Cycle Decomposition: (1,2,3)

julia> cycles(q)
2-element Vector{Vector{Int64}}:
 [1, 3]
 [2]

```

---

<div class="post-metadata">

**Author:** ![pg261](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pg261/32/24270_2.png) [@pg261](https://discourse.julialang.org/u/pg261)\
**Post date:** [May 20, 2021, 11:54am UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/5 "2021-05-20T11:54:26Z")

</div>

Thanks all for your answers! I had prepared a workaround similar to what @lmiq suggested at the end. (And yes @BLI, if my imports are qualified everything works.)

So I guess when you want to add a method to a function you really always have to be explicit about it, giving its full name `Module.f` if necessary. This is disappointing though – what would you do in the following situation?

You have some code, say some function `f(x)` that will work as soon as some other function, call it `cycles(x)` while we’re at it, exists with some prescribed behaviour. So say

```julia
function f(x)
    # bla bla
    s= cycles(x)
    # bla bla involving s
end

```

And then you want people to use your function `f `, after they have created a version of `cycles` that suits their needs – does something specific to their particular data type. How would people use it? if they merely create a function called `cycles`, without explicitly adding a method to an existing one, then name clashes will happen rapidly. There’s an example in my original post.

Perhaps I should say more appropriately that I would like to use `f` on some data types that have a function `cycles` _but written by people who have no knowledge of my little function f_… 🙂 So asking them to add a method to `MyPersonalModule.cycles` is not a serious option. And writing a workaround for each data type, as I will end up doing for my permutation things, is not great either.

In OOP, say in Python, I would do things like this all the time, writing code calling `x.cycles()` that will work for any object with a method called `cycles`.

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [May 20, 2021, 11:57am UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/6 "2021-05-20T11:57:30Z")

</div>

Unfortunately, this is one the pain points which will not go away (you may read [Function name conflict: ADL / function merging?](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335) to get the standing point of the Julia creators on this issue).

You can use external packages though, which are trying to mitigate it, for example [UsingMerge.jl](https://github.com/jmichel7/UsingMerge.jl). Unfortunately, it’s not in the general Registry yet, so one need to install it with

```julia
pkg> add git@github.com:jmichel7/UsingMerge.jl.git

```

Then you can add necessary functions through the `@usingmerge` macro

```julia
using UsingMerge
using AbstractAlgebra
@usingmerge Permutations: cycles

julia> p = perm"(1,2,3)"
(1,2,3)

julia> cycles(p)
Cycle Decomposition: (1,2,3)

```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [May 20, 2021, 12:08pm UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/7 "2021-05-20T12:08:21Z")

</div>

> [@pg261](#):
>
> And then you want people to use your function `f ` , after they have created a version of `cycles` that suits their needs – does something specific to their particular data type. How would people use it?

The fundamental problem here is that two packages could define two functions with the same name that do different things with _the same type_ of variable. Then what to do?

Your function is perfectly fine. But if one user wants to define a `cycles` function _and_ use a package that also defines a `cycles` function, he/she will have to qualify the use of the cycle function of that package, or, if that is what he/she wants, extend the methods of the functions of that package.

ps: In python you would be qualifying the names all the time, with `np.something()`, etc… To feel safe, you can do that in Julia as well, using `import` instead of `using`. But generic programming sort of gets lost there.

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [May 20, 2021, 12:21pm UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/8 "2021-05-20T12:21:35Z")

</div>

Example with python is misleading actually. Most of the time people use OOP in python, and class instances do not qualify methods, which is contrast to Julia with it’s multiple dispatch.

Compare

```python
class A:
   def __init__ (self):
      self.a = 1

   def foo(self):
      return self.a

```

if it is a part of some module `utils.py`, then usage will be

```python
import utils

a = utils.A()
a.foo()

```

Similar code in Julia is

```julia
module Utils

struct A
  a
end
A() = A(1)

foo(x::A) = x.a

end # module

```

and usage

```julia
using Utils

a = Utils.A()
Utils.foo(a)

```

You can see, that method call is different. Roughly speaking, in python fully qualified name of the method is inferred from the class. So, python equivalent of Julia code in this case would be

```python
a.utils.foo()

```

which is redundant.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [May 20, 2021, 12:32pm UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/9 "2021-05-20T12:32:38Z")

</div>

Indeed, but adding that `A.foo` there in python is a method that can only be applied to objects of type `A`, thus a new class of objects need a complete new implementation of `foo`. (that is the trade-off for never having name clashes)

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [May 20, 2021, 12:38pm UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/10 "2021-05-20T12:38:49Z")

</div>

Except of inheritance and mixins 🙂

But surely, each approach has its advantages and disadvantages. Fact that you need to almost always use fully qualified names of methods in Julia is one of such disadvantages (in my opinion). And it seems that it is impossible to solve it on a general level, due to the type piracy and other issues. Yet on the other hand `UsingMerge.jl` approach seems promising.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [May 20, 2021, 12:44pm UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/11 "2021-05-20T12:44:38Z")

</div>

> [@Skoffer](#):
>
> Fact that you need to almost always use fully qualified names of methods in Julia

Do you think that happens? I feel exactly the opposite, always never having to do that, the disadvantage being sometimes having to deal with these name clashes explicitly.

If you mean that in package development the addition of methods needs qualifying (explicit import), agreed, but from a _user_ perspective, those name clashes are not common, imo. It is much more common to see “qualified” names in the module model of python (which means really all the time).

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [May 20, 2021, 12:47pm UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/12 "2021-05-20T12:47:00Z")

</div>

> Do you think that happens?

We have this topic, so it happens.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [May 20, 2021, 12:48pm UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/13 "2021-05-20T12:48:08Z")

</div>

Not “almost always” 🙂

---

<div class="post-metadata">

**Author:** ![pg261](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pg261/32/24270_2.png) [@pg261](https://discourse.julialang.org/u/pg261)\
**Post date:** [May 20, 2021, 12:56pm UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/14 "2021-05-20T12:56:37Z")

</div>

Thanks, i’m going through the very long discussion following your link, this is quite a vast subject, it seems.

By the way, I don’t think my python example is misleading. I’m sure you already know what I’m going to write, but I mean that you can have in one file:

```julia
class Foo:
    def value(self):
        return 1

```

and then in some other file, written by someone else in a galaxy far, far away:

```julia
class Bar:
    def value(self):
        return -1
    # and please imagine that the rest of Foo and Bar are wildly different

```

Then one can write anywhere

```julia
print("the value of x is", x.value())

```

and it just works, whether `x` was created as a Foo or Bar or whatever. It’s always the right method.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [May 20, 2021, 12:58pm UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/15 "2021-05-20T12:58:36Z")

</div>

> [@pg261](#):
>
> I don’t think my python example is misleading.

I think he meant _my_ example.

---

<div class="post-metadata">

**Author:** ![pg261](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pg261/32/24270_2.png) [@pg261](https://discourse.julialang.org/u/pg261)\
**Post date:** [May 20, 2021, 1:00pm UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/16 "2021-05-20T13:00:26Z")

</div>

> [@lmiq](#):
>
> I think he meant _my_ example.

Oh, OK. My last post was a waste of time for everyone, sorry 🙂

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [May 20, 2021, 1:03pm UTC](https://discourse.julialang.org/t/functions-from-different-modules-with-the-same-name/61505/17 "2021-05-20T13:03:32Z")

</div>

You can probably use `methods(A.f)` and `methods(B.f)` to programmatically create glue methods.
