# Function name conflict: ADL / function merging?

**URL:** <https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335>\
**Category:** Internals & Design\
**Tags:** proposal, namespaces\
**Created:** [April 14, 2018, 5:16pm UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335 "2018-04-14T17:16:17Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [April 14, 2018, 5:16pm UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/1 "2018-04-14T17:16:17Z")

</div>

Is there any reason why Julia needs me to fully qualify the function name when the argument types are clear and there shouldn’t be any problem with multiple dispatch?

**Case 1: load JuliaDB before defining `Foo`**

```julia
julia> using JuliaDB

julia> stack(
stack(t::D) where D<:Union{IndexedTables.NDSparse, IndexedTables.NextTable} in IndexedTables at /Users/tomkwong/.julia/v0.6/IndexedTables/src/reshape.jl:32
stack(t::D, by; select, variable, value) where D<:Union{IndexedTables.NDSparse, IndexedTables.NextTable} in IndexedTables at /Users/tomkwong/.julia/v0.6/IndexedTables/src/reshape.jl:32
stack(t::Union{JuliaDB.DNDSparse, JuliaDB.DNextTable}) in JuliaDB at /Users/tomkwong/.julia/v0.6/JuliaDB/src/reshape.jl:7
stack(t::Union{JuliaDB.DNDSparse, JuliaDB.DNextTable}, by; select, variable, value) in JuliaDB at /Users/tomkwong/.julia/v0.6/JuliaDB/src/reshape.jl:7

julia> struct Foo end

julia> stack(f::Foo) = 1
ERROR: error in method definition: function IndexedTables.stack must be explicitly imported to be extended

```

**Case 2: define `Foo` before loading JuliaDB**

```julia
julia> struct Foo end

julia> stack(f::Foo) = 1
stack (generic function with 1 method)

julia> using JuliaDB
WARNING: using JuliaDB.stack in module Main conflicts with an existing identifier.

```

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [April 14, 2018, 5:27pm UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/2 "2018-04-14T17:27:18Z")

</div>

This is intended behaviour, see, [https://github.com/JuliaLang/julia/issues/18181](https://github.com/JuliaLang/julia/issues/18181), [https://github.com/JuliaLang/julia/issues/18427](https://github.com/JuliaLang/julia/issues/18427), [https://github.com/JuliaLang/julia/issues/22782](https://github.com/JuliaLang/julia/issues/22782)

---

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [April 14, 2018, 7:21pm UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/3 "2018-04-14T19:21:31Z")

</div>

Thanks for the references but I don’t fully understand the design decision here. The method signatures are clearly different for the two functions and they shouldn’t be any conflict.

Consider this example:

```julia
julia> module A 
                export foo
                struct ABC end
                foo(x::ABC) = 1
              end
A

julia> module B
                export foo
                struct XYZ end
                foo(x::XYZ) = 2
              end
B

julia> using A

julia> using B

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

```

Further, if these functions are not coming from different modules then multiple dispatch works beautifully. Why is importing (or `using`) any different?

```julia
julia> bar(x::A.ABC) = 1
bar (generic function with 1 method)

julia> bar(x::B.XYZ) = 2
bar (generic function with 2 methods)

julia> bar(A.ABC())
1

julia> bar(B.XYZ())
2

```

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [April 14, 2018, 7:33pm UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/4 "2018-04-14T19:33:52Z")

</div>

Multiple dispatch _only_ works for different methods of the _same function_. Your example consists of two completely different functions that happen to have the same name. To add methods to an existing function in another module, you always have to `import` that function or use its fully-qualified name when defining the method. Otherwise you’re just creating a completely new function which also happens to be called `foo`.

This is intentional because the alternative would be chaos. The requirement to use an `import` or a fully-qualified name clearly indicates that you _want_ to extend an existing function with a new method. If that requirement were eliminated, then completely unrelated packages would end up conflicting with one another because both Module A and Module B defined `foo(::Int)`. The result would be type piracy everywhere.

---

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [April 14, 2018, 9:40pm UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/5 "2018-04-14T21:40:03Z")

</div>

Thanks for the detailed explanation. I think this statement covers it well as far as the mechanics of multiple dispatch.

> [@rdeits](#):
>
> Multiple dispatch only works for different methods of the same function. Your example consists of two completely different functions that happen to have the same name.

Perhaps it should be a feature request. IMHO, defining a function with my own types (hence not a type piracy problem) that happens to have the same name as an exported function from a dependent package should still be allowed. There’s no ambiguity.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [April 14, 2018, 10:27pm UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/6 "2018-04-14T22:27:51Z")

</div>

> [@tk3369](#):
>
> IMHO, defining a function with my own types (hence not a type piracy problem) that happens to have the same name as an exported function from a dependent package should still be allowed.

It is? But obviously, if you use two packages that export two different things with the same name, there will be a conflict. If you wanted to extend the function, then do so.

---

<div class="post-metadata">

**Author:** ![ssfrr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ssfrr/32/3736_2.png) [@ssfrr](https://discourse.julialang.org/u/ssfrr)\
**Post date:** [April 15, 2018, 2:27am UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/7 "2018-04-15T02:27:33Z")

</div>

> [@tk3369](#):
>
> IMHO, defining a function with my own types (hence not a type piracy problem) that happens to have the same name as an exported function from a dependent package should still be allowed. There’s no ambiguity.

I agree that it wouldn’t be a type piracy issue if Julia let you define your own `stack` function in this way (which would be separate from the `stack` function exported by the dependent package), so then locally the identifier `stack` would point to your function rather than the existing one.

The trade-off is that if you actually _did_ intend to extend the existing `stack`, things are broken in a subtle and confusing way. I don’t have any data on this, but my hunch is that extending functions is far more common than defining new functions with the same name as an existing one. I’m guessing this error is thrown to prevent that situation.

Note this is also an argument for `using Foo: bar, baz` to be explicit about what names you pull into your local namespace, so if you did want to define your own `stack` function, you wouldn’t `using` it.

---

<div class="post-metadata">

**Author:** ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)\
**Post date:** [April 15, 2018, 2:35am UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/8 "2018-04-15T02:35:54Z")

</div>

Actually I find none of the answers convincing. I met this problem in my code and I think there is no good solution. I have a package implementing polynomials and there is naturally a `degree` method for them.  
Then later I wrote a package for permutations and I wrote a method `degree` for them (for a permutation  
`degree` is how many points they move). I can use one or the other package without problem. But, If I use  
both together I got the same dreaded message about the need to qualify the function.

The only workaround I found is to have a `dummy` package which defines the function and have each package extend the definition from dummy. I find this a ugly hack.

I think the only reason that the current situation in julia is iivable is because quite often the function one  
wants to extend (like the arithmetic operations +, \*, / etc…) is in base. Then it is not painful that each package imports from base then extends.  
A solution would be if one could add names to base. Otherwise I do not know what is a good solution.

---

<div class="post-metadata">

**Author:** ![ssfrr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ssfrr/32/3736_2.png) [@ssfrr](https://discourse.julialang.org/u/ssfrr)\
**Post date:** [April 15, 2018, 3:20am UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/9 "2018-04-15T03:20:57Z")

</div>

> [@Jean\_Michel](#):
>
> A solution would be if one could add names to base. Otherwise I do not know what is a good solution.

It’s pretty common for ecosystems of related packages in Julia to have an “xBase” (like StatsBase.jl or DiffEqBase.jl that defines shared functions and types for different packages in the ecosystem to extend. These packages also can be points of collaboration between people working in related domains.

I agree it’s a trade-off and takes some coordination between the different packages that use the shared functions. The alternative of automatically merging together functions with the same name has been discussed before, but that has trade-offs of its own.

I’d definitely be curious to hear if you have a proposal for a better solution.

---

<div class="post-metadata">

**Author:** ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)\
**Post date:** [April 15, 2018, 3:25am UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/10 "2018-04-15T03:25:05Z")

</div>

I think I suggested a possibility: the possibility to add names to base (just adding empty definitions).  
At least then one would not have to invent a dummy name for a glue package.

---

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [April 15, 2018, 4:25am UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/11 "2018-04-15T04:25:39Z")

</div>

> [@ssfrr](#):
>
> Note this is also an argument for using Foo: bar, baz to be explicit about what names you pull into your local namespace, so if you did want to define your own stack function, you wouldn’t using it.

This is probably the best approach for now…

It would be nice if doing so it also cuts down the time for compilation as I only use a fraction of the functionalities from the package?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [April 15, 2018, 7:20am UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/12 "2018-04-15T07:20:22Z")

</div>

> [@tk3369](#):
>
> It would be nice if doing so it also cuts down the time for compilation as I only use a fraction of the functionalities from the package?

Functions can call other functions. It is impossible to know what functions in the package will end up getting called.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 15, 2018, 10:06am UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/13 "2018-04-15T10:06:50Z")

</div>

> [@Jean\_Michel](#):
>
> the possibility to add names to base (just adding empty definitions)

Think about the implications of this suggestion. The space of function names is (practically) infinite, so a large and asymptotically growing part of `Base` would be

```julia
function a_function_that_two_people_use end
export a_function_that_two_people_use

function another_function_that_is_kindof_handy end
export another_function_that_is_kindof_handy

```

The `export`s are optional (your proposal did not specify — and of course we would use macros 😉).

The current solution of explicitly importing (and resolving ambiguities when necessary) is much better. There are always trade-offs between verbosity, ambiguity, and clashes, but the _status quo_ is kind of a sweet spot:

1. it works without a hitch if there is no overlap between exported symbols,
2. asks for explicit action when there is one,
3. and distinguishes _using_ and _extending_ functions by requiring the latter to be explicit.

Also, some packages choose not to `export` _any_ of their interface (eg [ForwardDiff.jl](https://github.com/JuliaDiff/ForwardDiff.jl)) and require explicit imports, which is also a valid design choice.

> [@Jean\_Michel](#):
>
> have a dummy package which defines the function and have each package extend the definition from dummy. I find this a ugly hack.

I find this a very nice and clean solution. Packages are very lightweight in Julia, making it very easy to make and use small ones. Many collections of packages do this, and it will become even nicer with `Pkg3`.

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [April 15, 2018, 11:54am UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/14 "2018-04-15T11:54:38Z")

</div>

> [@Tamas\_Papp](#):
>
> Packages are very lightweight in Julia, making it very easy to make and use small ones.

Perhaps computationally lightweight, but maintaining small packages is a chore. They feel like C++ header files: redundant work.

> [@Tamas\_Papp](#):
>
> Many collections of packages do this, and it will become even nicer with Pkg3.

Haven’t followed Pkg3. Does it have a solution to this problem?

IMHO the best solution would be to allow defining `Polynomials.degree(m::MyType) = ...` without having to fully import and REQUIRE `Polynomials`. Then we wouldn’t need interface-defining packages. But it’s not trivial design-wise.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 15, 2018, 12:05pm UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/15 "2018-04-15T12:05:33Z")

</div>

> [@cstjean](#):
>
> Haven’t followed Pkg3. Does it have a solution to this problem?

My understanding is that it will make it easier to specify (potentially unregistered) dependencies, and has faster download/install times. This should make these small extra packages essentially unnoticeable by the user, and very cheap for the developer.

> [@cstjean](#):
>
> maintaining small packages is a chore. They feel like C++ header files: redundant work

I don’t understand how it is redundant in this instance. This is something that needs to be specified by the developer, the language cannot infer this otherwise.

> [@cstjean](#):
>
> best solution would be to allow defining `Polynomials.degree(m::MyType) = ...` without having to fully import and REQUIRE `Polynomials`

If I understand correctly, `Pkg3` would allow multiple packages with the same name and/or version to coexist. So I don’t see how a detailed specification of the requirements could be avoided.

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [April 15, 2018, 12:16pm UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/16 "2018-04-15T12:16:52Z")

</div>

> [@Tamas\_Papp](#):
>
> I don’t understand how it is redundant in this instance. This is something that needs to be specified by the developer, the language cannot infer this otherwise.

Perhaps we’re talking about two different things. I’m talking about a package like ScikitLearnBase.jl, whose main content is a bunch of forward declaration.

```julia
function fit! end
function predict end
function is_classifier end
...

```

Those functions already have full definitions in `ScikitLearn.jl`. Why do I have to define them in ScikitLearnBase.jl again? We only go through this because package X wants to be able to support package Y without imposing Y’s full loading time on X users who don’t care about Y. If packages were as fast to load and as lightweight as Python packages (… a tall order, I know), X would just `import Y`.

---

<div class="post-metadata">

**Author:** ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)\
**Post date:** [April 15, 2018, 4:34pm UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/17 "2018-04-15T16:34:28Z")

</div>

I do not agree it is a nice and clean solution.

Author A develops package A (say “polynomials”) exporting function `degree` and then author B develops  
package B (say “permutations”) exporting function `degree`. If user C wants to use both packages he has  
no way to use degree without qualification. If authors A and B are the same person she can think forward and  
make a package `dummy_declaring_degree` and have both A and B importing and extending `degree` from this dummy package. If authors A and B are different persons and do not communicate C is screwed up.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 15, 2018, 5:19pm UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/18 "2018-04-15T17:19:34Z")

</div>

> [@Jean\_Michel](#):
>
> If authors A and B are different persons and do not communicate C is screwed up.

I think is best to abstain from hyperbole: the worst case scenario is the user having to resolve the ambiguity manually (via `using`/`import`, declaring abbreviations for package names with `const`, etc).

If two packages share verbs (functions) that are similar, the best case scenario is that the maintainers cooperate to put these in a third package. This does happen in practice, eg see

> **[GitHub - JuliaStats/StatsBase.jl: Basic statistics for Julia](https://github.com/JuliaStats/StatsBase.jl)**
>
> Basic statistics for Julia. Contribute to JuliaStats/StatsBase.jl development by creating an account on GitHub.

Eventually, all these issues boil down to people being reasonable and cooperating when applicable. I don’t think this is a bad outcome, and more importantly, it is not clear how one can improve on this while preserving separate namespaces.

---

<div class="post-metadata">

**Author:** ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)\
**Post date:** [April 15, 2018, 5:22pm UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/19 "2018-04-15T17:22:10Z")

</div>

> [@Tamas\_Papp](#):
>
> I think is best to abstain from hyperbole: the worst case scenario is the user having to resolve the ambiguity manually (via using/import, declaring abbreviations for package names with const, etc).

Can you be more specific and show me? I am here to learn…

---

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [April 15, 2018, 5:32pm UTC](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/20 "2018-04-15T17:32:49Z")

</div>

This discussion reminds me of a best practice when writing Java code. Import statements should be written explicitly so the namespace isn’t polluted with unnecessary dependencies. Here’s a sample [reference post](https://stackoverflow.com/questions/147454/why-is-using-a-wild-card-with-a-java-import-statement-bad#147461).

If I would explicitly import specific functions from the dependent package then there’s no conflict. Ideally, a good IDE would auto generate the `using` statements for me. When I use Eclipse for Java, it’s a single click.

```julia
julia> module A 
             export foo
             struct ABC end
             foo(x::ABC) = 1
             bar() = 2
         end
A

julia> module B
              export foo
              struct XYZ end
              foo(x::XYZ) = 3
          end
B

julia> using A: bar

julia> using B

julia> foo(B.XYZ())
3

julia> bar()
2

```

[Next page](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335.md?page=2)
