# How does Julia dispatch on concrete methods?

**URL:** <https://discourse.julialang.org/t/how-does-julia-dispatch-on-concrete-methods/51647>\
**Category:** New to Julia\
**Tags:** method-extension\
**Created:** [December 11, 2020, 4:51am UTC](https://discourse.julialang.org/t/how-does-julia-dispatch-on-concrete-methods/51647 "2020-12-11T04:51:54Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![eschoute](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eschoute/32/8298_2.png) [@eschoute](https://discourse.julialang.org/u/eschoute)\
**Post date:** [December 11, 2020, 4:51am UTC](https://discourse.julialang.org/t/how-does-julia-dispatch-on-concrete-methods/51647/1 "2020-12-11T04:51:54Z")

</div>

Hi all,

I’m trying to understand how Julia figures out what functions to call when we implement an interface from say a library (or from some other module). That library has some functions that then are able to call the concrete implementations of the interface. I tried to model that in the following example but it doesn’t seem to work.

```julia
module World
module ModA
​
abstract type AbstractFoo end
struct Foo <: AbstractFoo end
​
function foo(x :: AbstractFoo)
    return length(x) + 1
end
​
function length(x :: Foo)
    return 10
end
​
end
​
​
module ModB
import ..ModA
​
struct Bar <: ModA.AbstractFoo end
​
function length(x :: Bar)
    return 42
end
​
end
end
​
World.ModA.foo(World.ModB.Bar())

```

Here ModA providces a concrete implementation of `AbstractFoo`, `Foo`. But say I want to make my own `AbstractFoo` so I implement `Bar` and the required method `length` in my ModB. Now I want to use the functionality `foo`, but I get an error.  
Alternatively, I tried bringing everything into scope.

```julia
module World
module ModA
​
abstract type AbstractFoo end
struct Foo <: AbstractFoo end
​
function foo(x :: AbstractFoo)
    return length(x) + 1
end
​
function length(x :: Foo)
    return 10
end
​
export
    AbstractFoo,
    Foo,
    foo,
    length
end
​
​
using .ModA
​
Foo()
​
module ModB
using ..ModA
​
struct Bar <: AbstractFoo end
​
function length(x :: Bar)
    return 42
end
​
export
    Bar,
    length
end
​
using .ModB
foo(Bar())
​
end

```

This also doesn’t work. What is the reason that this doesn’t work? And how does this work for the libraries that are out there?

As an aside, I tried writing this without the `World` module surrounding both but importing the code from ModA was giving me some difficulties that I’m not entirely sure what caused them.

---

<div class="post-metadata">

**Author:** ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)\
**Post date:** [December 11, 2020, 9:13am UTC](https://discourse.julialang.org/t/how-does-julia-dispatch-on-concrete-methods/51647/2 "2020-12-11T09:13:13Z")

</div>

It doesn’t work because `ModA.length` and `ModB.length` are two different functions and `ModA.foo` calls `ModA.length`. To extend `ModA.length` in `ModB` instead of creating a new function `ModB.length`, you need to qualify it or import it explicitly, i.e., either

```julia
import ..ModA

function ModA.length(x::Bar)
    return 42
end

```

or

```julia
import ..ModA: length

function length(x::Bar)
    return 42
end

```

Edit: The table in [this section of the manual](https://docs.julialang.org/en/v1/manual/modules/#Summary-of-module-usage) shows what is brought into scope and what functions are made available to extend by `using`/`import`.

---

<div class="post-metadata">

**Author:** ![eschoute](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eschoute/32/8298_2.png) [@eschoute](https://discourse.julialang.org/u/eschoute)\
**Post date:** [December 11, 2020, 3:29pm UTC](https://discourse.julialang.org/t/how-does-julia-dispatch-on-concrete-methods/51647/3 "2020-12-11T15:29:07Z")

</div>

Thanks, I missed that there is such a qualifier as “method extension”. It is not defined on the page you linked to either. I wonder now how it works, does Julia keep a table of functions that go by the same name when defined with the “method extension” available? How does Julia know here to call ModB.length (it is not exported)?

Here is the working example

```julia
module World
module ModA

abstract type AbstractFoo end
struct Foo <: AbstractFoo end

function foo(x :: AbstractFoo)
    return println(length(x))
end

function length(x :: Foo)
    return 10
end

export
    AbstractFoo,
    Foo,
    foo    
end

module ModB
using ..ModA
import ..ModA: length

struct Bar <: AbstractFoo end

function length(x :: Bar)
    return 42
end

export
    Bar
end

using .ModA
using .ModB
foo(Foo())
foo(Bar())

end

```

---

<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:** [December 11, 2020, 5:48pm UTC](https://discourse.julialang.org/t/how-does-julia-dispatch-on-concrete-methods/51647/4 "2020-12-11T17:48:30Z")

</div>

Functions have an identity in Julia, and every method unambiguously belongs to a single function. When you do:

```julia
function foo(x)
  bar()
end

```

or, equivalently, `foo(x) = bar()`

then the following happens:

- If you have already done `import OtherPackage: foo` in the current module, then a new _method_ is added to the existing _function_ `OtherPackage.foo`
- Otherwise a new function is created in your current module and a single method is added to it.

You can always see the set of methods attached to a given function with `methods(foo)`.

When you do: `function OtherPackage.foo(...)` or `OtherPackage.foo(...) = ...`, then you are unambiguously adding a new _method_ to the existing _function_.

Your `ModB` is creating a brand-new function called “length”. This has nothing at all to do with `ModA.length`–the fact that they share a name is of no consequence whatsoever (this is completely different than C++, for example). You need to either explicitly `import ModA: length` or define the function directly as `ModA.length`. The latter is recommended because it makes the behavior obviously correct.
