# Multiple Dispatch Across Seperate Files

**URL:** https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480
**Category:** General Usage
**Created:** [December 27, 2020, 10:26pm UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480 "2020-12-27T22:26:21Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![Kieran\_Gill](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kieran_gill/32/20587_2.png) [@Kieran\_Gill](https://discourse.julialang.org/u/Kieran_Gill)
#### Post date: [December 27, 2020, 10:26pm UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/1 "2020-12-27T22:26:21Z")

</div>

I am attempting to use the same function `forward` in different contexts.

Layers.jl

```julia
module Layers

export Dense, forward

struct Dense
    n_inputs
    n_neurons
    weights
    biases
    function Dense(n_inputs, n_neurons)
        ### Intialize weights and biases
        ...
        new(n_inputs, n_neurons, weights, biases)
    end
end

function forward(layer::Dense, inputs)
    if layer.n_inputs != size(inputs, 2)
        throw(DimensionMismatch("Input size does not match layer input size"))
    end

    return (inputs * layer.weights) .+ layer.biases
end

end

```

Activations.jl

```julia
module Activations

export forward, ReLU

abstract type ReLU end

function forward(layer::Type{ReLU}, data)
    return map(x -> max(0, x), data)
end

end

```

main.jl

```julia

using .Layers
using .Activations

dense1 = Dense(2, 4)

inputs = [[1 2]; [3 4]; [3 5]]

out = forward(dense1, inputs)
forward(ReLU, out)

```

On the last line, I get an error saying that `forward` does not have an overload for ReLU:

```julia
julia> forward(ReLU, out)
ERROR: MethodError: no method matching forward(::Type{ReLU}, ::Array{Float64,2})
Closest candidates are:
  forward(::Dense, ::Any) at /Users/user/Documents/test/Layers.jl:33
Stacktrace:
 [1] top-level scope at REPL[106]:

```

Is there a correct way to pull in functions with the same name from multiple different files to use multiple dispatch?

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [December 27, 2020, 11:08pm UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/2 "2020-12-27T23:08:14Z")

</div>

The problem is that you have 2 different functions named `forward` instead of 1 function with 2 methods. The solution is to make one (or both) of `Layers` and `Activations` import `forward` before defining it.

---

<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: [December 27, 2020, 11:56pm UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/3 "2020-12-27T23:56:01Z")

</div>

I think that deserves a design explanation. Naively I would expect that to work and to raise a warning if a method overwrites the other.

Of course for third party modules the alternative is to `import`. But it is somewhat scary that that kind of overwrite can happen without notice when loading multiple modules.

---

<div class="post-metadata">

### Author: ![Kieran\_Gill](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kieran_gill/32/20587_2.png) [@Kieran\_Gill](https://discourse.julialang.org/u/Kieran_Gill)
#### Post date: [December 28, 2020, 3:43am UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/4 "2020-12-28T03:43:10Z")

</div>

Hi, thanks for your reply. I’m still having a bit of an issue doing it this way. I tried following [this](https://stackoverflow.com/questions/30228282/overloading-a-function-in-two-files-in-julia) and reading [this](https://docs.julialang.org/en/v1/manual/methods/) documentation, yet I’m still unsure as to where I’m going wrong.

New file NNFS.jl

```julia
module NNFS

export forward

forward(layer, data) = begin
    throw("You need to overload base forward for $(typeof(layer)) and $(typeof(data))")
end

end

```

Modified `Layers.jl`

```julia
module Layers

using Random; Random.seed!(0)
include("NNFS.jl")
import .NNFS.forward

struct Dense
    n_inputs
    n_neurons
    weights
    biases
    function Dense(n_inputs, n_neurons)
        ### Initialize weights and biases
        ...
        new(n_inputs, n_neurons, weights, biases)
    end
end

NNFS.forward(layer::Dense, inputs::Array{Float64,2}) = begin
    if layer.n_inputs != size(inputs, 2)
        throw(DimensionMismatch("Input size does not match layer input size"))
    end

    return (inputs * layer.weights) .+ layer.biases
end

export Dense

end

```

Main file:

```julia
include("NNFS.jl")
include("Layers.jl")
using .NNFS: forward
using .Layers

dense1 = Dense(2, 4)

inputs = [[1. 2.]; [3. 4.]; [3. 5.]]

out = forward(dense1, inputs)

```

The last line gets the error (which I defined)

```julia
ERROR: "You need to overload base forward for Dense and Array{Float64,2}"
Stacktrace:
 [1] forward(::Dense, ::Array{Float64,2}) at /Users/user/test/NNFS.jl:6
 [2] top-level scope at REPL[7]:1

```

And calling `methods` on forward gives the following

```julia
julia> methods(forward)
# 1 method for generic function "forward":
[1] forward(layer, data) in Main.NNFS at /Users/user/test/NNFS.jl:5

```

What is the correct way to set up function overloading from multiple different files?

---

<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 28, 2020, 4:58am UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/5 "2020-12-28T04:58:25Z")

</div>

> [@lmiq](#):
>
> I think that deserves a design explanation. Naively I would expect that to work and to raise a warning if a method overwrites the other.

There’s no overwriting going on–there are just two different functions: `Layers.forward` and `Activations.forward` which have nothing whatsoever to do with one another. Neither interferes with the other, but they can’t both participate in multiple dispatch because they are fundamentally different functions.

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [December 28, 2020, 5:01am UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/6 "2020-12-28T05:01:49Z")

</div>

The reason for this is that making a new function by default means you only need to be aware of the functions you extend. If a new method was created by default, any package (or Base) adding a new function would be a potentially breaking change.

---

<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 28, 2020, 5:01am UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/7 "2020-12-28T05:01:59Z")

</div>

> [@Kieran\_Gill](#):
>
> What is the correct way to set up function overloading from multiple different files?

The problem in your case is that you’ve now included `NNFS.jl` in two different places–once inside `Layers.jl` and again in your main file. Those separate `include()s` have created two completely unrelated modules which happen to have the same name. That’s why it’s important _not_ to include the same file multiple times. Here’s a post with a similar question on avoiding multiple includes that you might find helpful: [Need to include one file multiple times, how to avoid warning - #5 by rdeits](https://discourse.julialang.org/t/need-to-include-one-file-multiple-times-how-to-avoid-warning/27439/5)

In your case, you should be able to replace:

```julia
include("NNFS.jl")
import .NNFS: forward

```

with

```julia
import ..NNFS: forward

```

in `Layers.jl`

---

<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: [December 28, 2020, 5:46am UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/8 "2020-12-28T05:46:39Z")

</div>

My blog post may be helpful:

[https://www.ahsmart.com/pub/the-meaning-of-functions/](https://www.ahsmart.com/pub/the-meaning-of-functions/)

This is also the reason why you sometimes see _Whatever_Base.jl packages because they are used to define functions that are expected to be extended.

---

<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: [December 28, 2020, 9:44am UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/10 "2020-12-28T09:44:31Z")

</div>

I am sorry, there is indeed an error raised, so that is fine:

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

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

julia> using .Pkg1; using .Pkg2

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

julia> 

```

My first impression from the original post was that didn’t raise any error or warning.

Also, I do not understand how did you get the `no method matching forward...` error. You should have gotten a warning on the impossibility of using `forward` from two modules without explicitly importing them, and then `forward not defined` errors. Here is what happens here, reproducing your initial post with some simplifications:

```julia
julia> module Layers
         export Dense, forward
         struct Dense x end
         forward(x::Dense) = "from Layers"
       end
Main.Layers

julia> module Activations
         export ReLU, forward
         abstract type ReLU end
         forward(x::Type{ReLU}) = "from Activations"
       end
Main.Activations

julia> using .Layers

julia> using .Activations

julia> dense1 = Dense(1)
Dense(1)

julia> forward(dense1)
WARNING: both Activations and Layers export "forward"; uses of it in module Main must be qualified
ERROR: UndefVarError: forward not defined
Stacktrace:
 [1] top-level scope at REPL[6]:1

julia> forward(ReLU)
ERROR: UndefVarError: forward not defined
Stacktrace:
 [1] top-level scope at REPL[7]:1

julia> 

```

---

<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: [December 28, 2020, 10:13am UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/11 "2020-12-28T10:13:49Z")

</div>

Concerning the original question, here is a simplified version which might help to understand what is going on:

NNFS.jl:

```julia
module NNFS
export forward
forward(layer) = "original"
end

```

Layers.jl:

```julia
module Layers
include("NNFS.jl")
import .NNFS.forward
struct Dense
  x
end
NNFS.forward(layer::Dense) = "overloaded"
export Dense
end

```

main.jl:

```julia
include("NNFS.jl")
include("Layers.jl")
using .NNFS: forward
using .Layers

dense = Dense(1)

println(forward(dense))
println(Layers.forward(1.0)) # not Dense
println(Layers.forward(dense))
println(Layers.NNFS.forward(dense))

```

Results in:

```julia
julia> include("./main.jl")
"original"
"original"
"overloaded"
"overloaded"

```

As you see, you are overloading the `forward` function from `NNFS`, but that is visible only on the `NNFS` version which lives inside `Layers`. There are two versions of `NNFS`, because of the double include, as explained.

---

<div class="post-metadata">

### Author: ![Kieran\_Gill](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kieran_gill/32/20587_2.png) [@Kieran\_Gill](https://discourse.julialang.org/u/Kieran_Gill)
#### Post date: [December 29, 2020, 3:06am UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/12 "2020-12-29T03:06:36Z")

</div>

Thank you! Is there an explanation on `.` vs `..` available somewhere? The only mention of it I can find in the documentation is [here](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Global-Scope).

Typically the difference between `.` and `..` is to specify cwd or parent directory; so, I’m a bit surprised to see it being used like this.

---

<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 29, 2020, 4:28am UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/13 "2020-12-29T04:28:38Z")

</div>

> [@Kieran\_Gill](#):
>
> Thank you! Is there an explanation on `.` vs `..` available somewhere? The only mention of it I can find in the documentation is [here](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Global-Scope).

It’s explained at the end of this section: [Modules · The Julia Language](https://docs.julialang.org/en/v1/manual/modules/#Relative-and-absolute-module-paths)

The analogy to `cwd` or the parent directory is intentional: the `..` means to look in the parent module.

---

<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: [December 29, 2020, 2:59pm UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/14 "2020-12-29T14:59:40Z")

</div>

Here is an example: [Difference between "using x" vs "using .x" or "using Main.x" - #2 by lmiq](https://discourse.julialang.org/t/difference-between-using-x-vs-using-x-or-using-main-x/52269/2)

---

<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: [December 29, 2020, 3:13pm UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/15 "2020-12-29T15:13:29Z")

</div>

> [@Kieran\_Gill](#):
>
> The only mention of it I can find in the documentation is [here](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Global-Scope).

Note that the modules chapter was rewritten significantly in 1.6/master, see

[https://docs.julialang.org/en/v1.7-dev/manual/modules/](https://docs.julialang.org/en/v1.7-dev/manual/modules/)

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [December 29, 2020, 4:00pm UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/16 "2020-12-29T16:00:27Z")

</div>

I recommend against using submodules, for the majority of use cases. (not all, but most)  
It leads too problems like this too easily.  
Either use seperate packages and load them via `using` or `import`.  
Or use seperate files and `include` them, with only the main file having a `module` declaration.  
Not seperate files containing `module`s `include`ed into each other.

At least initially, just put everything in one big namespace.  
Namespaces are over-rated, lets have less of them.  
This may be counter to your experience in other languages (it was for me), but julia is a different language to others.  
And submodules just allow for extra mistakes, and require extra book-keeping.  
You can always later decide to split things into seperate packages (or seperate submodules if you really want), but until you have a reason to, just put it all in the same namespace.

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [December 29, 2020, 4:35pm UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/17 "2020-12-29T16:35:20Z")

</div>

I think your comment could be summarized to “using submodules is non-trivial/‘very different from other languages’ so beginners should avoid it if possible”. Obviously, any language feature may be wrongly used or overused. However, without talking about specifics it is impossible to draw the line. I use multiple submodules (with “seperate files containing modules `include`ed each other”) and have yet to experience any problems regarding this. Nor I have any reason to break my package into multiple packages.

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [December 29, 2020, 4:44pm UTC](https://discourse.julialang.org/t/multiple-dispatch-across-seperate-files/52480/18 "2020-12-29T16:44:25Z")

</div>

One of my favourite quotes is from the introduction of  
Press, Teukolsky, Vetting and Flannery’s “Numerical Recipes”:

> We do, therefore, offer you our practical judgements wherever we can. As you gain experience, you will form your own opinion of how reliable our advice is. Be assured that it is not perfect!

This is my advise, your mileage may vary.  
Be assured that there are many viable ways to do things, and this is just the one I personally recommend.
