# Multiple dispatch and modules

**URL:** <https://discourse.julialang.org/t/multiple-dispatch-and-modules/59700>\
**Category:** New to Julia\
**Tags:** module, dispatch\
**Created:** [April 20, 2021, 10:12pm UTC](https://discourse.julialang.org/t/multiple-dispatch-and-modules/59700 "2021-04-20T22:12:17Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![lambdakappatheta](https://avatars.discourse-cdn.com/v4/letter/l/bbce88/32.png) [@lambdakappatheta](https://discourse.julialang.org/u/lambdakappatheta)\
**Post date:** [April 20, 2021, 10:12pm UTC](https://discourse.julialang.org/t/multiple-dispatch-and-modules/59700/1 "2021-04-20T22:12:17Z")

</div>

After watching Stefan Karpinski’s talk called [The Unreasonable Effectiveness of Multiple Dispatch](https://www.youtube.com/watch?v=kc9HwsxE1OY) I started wondering how multiple dispatch and modules fit together.

To put it simply, if type `A` is defined in module `a` and type `B` is defined in module `b`, then where to define a method `f` that takes both an `A` and a `B` as its arguments?

From the client’s perspective, is `f` automatically imported if `A` and `B` are in scope?

Stefan talks about the exponential expressive power of multiple dispatch. The module systems I am familiar with have a tree-like structure and, as far as I can tell from skimming through the docs, the module system of Julia is no different: a module can have multiple children but only one parent. However, it seems to me that, intuitively, I would want to put `f` into a module that is a child of both `a` and `b`. In other words, it seems to me that the expressive power of a tree-like module system is at odds with the exponential expressive power of multiple dispatch.

Admittedly, I haven’t read every line of the [manual](https://docs.julialang.org/en/v1/), just browsed through it because I felt like it contains a lot of information I already know and I did not seem to find the things I was looking for.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [April 20, 2021, 11:13pm UTC](https://discourse.julialang.org/t/multiple-dispatch-and-modules/59700/2 "2021-04-20T23:13:37Z")

</div>

> [@lambdakappatheta](#):
>
> To put it simply, if type `A` is defined in module `a` and type `B` is defined in module `b` , then where to define a method `f` that takes both an `A` and a `B` as its arguments?

Either one, whichever you prefer. Something important to know is that method tables are global. That means if you have access to a function `f`, you also have access to all of its methods no matter where they are defined. But you do need to be able to access the function, and that follows the tree pattern you describe. Though, Base acts like a broad root, defining many functions that you can extend with your types and interoperate with other packages.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [April 21, 2021, 3:22am UTC](https://discourse.julialang.org/t/multiple-dispatch-and-modules/59700/3 "2021-04-21T03:22:44Z")

</div>

It’s common to make a third module `FooBar` that knows about both `Foo` and `Bar`. There are many examples like `SampleChainsDynamicHMC` that knows about `SampleChains` and `DynamicHMC`, or `AbstractGPsMakie` that knows about `AbstractGPs` and `Makie`.

---

<div class="post-metadata">

**Author:** ![lambdakappatheta](https://avatars.discourse-cdn.com/v4/letter/l/bbce88/32.png) [@lambdakappatheta](https://discourse.julialang.org/u/lambdakappatheta)\
**Post date:** [April 22, 2021, 11:07am UTC](https://discourse.julialang.org/t/multiple-dispatch-and-modules/59700/4 "2021-04-22T11:07:21Z")

</div>

Thank you both for your replies!

So how do people find the functions they need in Julia? Do they check the module `Foo` was defined in then check the module `Bar` was defined in and then look for `FooBar` or `BarFoo`?

How about functions with more than 2 arguments? Are there modules like `FooBarBaz` that contain functions that take a `Foo`, a `Bar` and a `Baz`?

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [April 23, 2021, 7:54am UTC](https://discourse.julialang.org/t/multiple-dispatch-and-modules/59700/5 "2021-04-23T07:54:34Z")

</div>

> [@lambdakappatheta](#):
>
> So how do people find the functions they need in Julia?

[`methodswith`](https://docs.julialang.org/en/v1/stdlib/InteractiveUtils/#InteractiveUtils.methodswith) is a useful way to find all methods applying to at least an argument of the provided type (regardless of where these methods are defined).

---

<div class="post-metadata">

**Author:** ![ChunXi\_Zhang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chunxi_zhang/32/22556_2.png) [@ChunXi\_Zhang](https://discourse.julialang.org/u/ChunXi_Zhang)\
**Post date:** [April 23, 2021, 8:44am UTC](https://discourse.julialang.org/t/multiple-dispatch-and-modules/59700/6 "2021-04-23T08:44:13Z")

</div>

you can just using A and B, and then start define your f(x::a\_struct, y::b\_struct).  
you can define such f in any place where there is A and B, which is not a child of A or B. a child module, is a module defined inside another module. And as far as i know, people don’t use submodule in julia world as much as python world. Since in python every file is a module, but in julia, people can seperate code in different files and then include them.

and for the question of how I find the proper function for object as newbie: Google it.

for example it’s hard to remember where to find a random ralated function, when you have Distrubutions, Random, StatsBase and Base.rand, and they do interact with each other.  
i just guess how people would call that function, and search for it…

---

<div class="post-metadata">

**Author:** ![FPGro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fpgro/32/20822_2.png) [@FPGro](https://discourse.julialang.org/u/FPGro)\
**Post date:** [April 23, 2021, 10:00am UTC](https://discourse.julialang.org/t/multiple-dispatch-and-modules/59700/7 "2021-04-23T10:00:35Z")

</div>

> [@lambdakappatheta](#):
>
> How about functions with more than 2 arguments? Are there modules like `FooBarBaz` that contain functions that take a `Foo` , a `Bar` and a `Baz` ?

The point that Eric made above means that you don’t need those. If you write generic functions, then the function doesn’t have to know about the types it will be called with. The only time when you need to know a type is for specializing functions, and that can happen anywhere.  
It’s probably best with an example. Consider:

```julia
julia> module Foo
           function foo(first, second, third)
               return sum(first[second] .+ third) ^ second
           end
       end
Main.Foo

```

`Foo.foo` does not know what it’s arguments are, nor does it care. What matters is, that the parts of which `foo` is composed are defined. So we need to have the methods for

```julia
result1 = first[second] # getindex(first, second)
result2 = .+(result1, third)
result3 = sum(result2)
result4 = result3 ^ second # ^(result3, second)

```

And where these live doesn’t matter much.

```julia
julia> module Bars
           struct Bar end
           const bar = Bar()
           Base.getindex(::Bar, ind) = (2*ind)^(ind/2)
           Base.getindex(::Bar, ind, tail...) = bar[ind] + bar[tail...]
       end
Main.Bars

julia> module Baz
           abstract type AbstractBaz end
           # suppose we define our AbstractBaz interface so that every concrete Baz need getvalue(::Baz) defined
           getvalue(b::AbstractBaz) = error("The AbstractBaz interface demands that you define a specialized `getvalue(::$(typeof(b)))` method.")
           Base.:*(something::T, b::AbstractBaz) where {T} = *(something, getvalue(b))
           Base.:/(b::AbstractBaz, something::T) where {T} = /(getvalue(b), something)
           Base.:^(something::T, b::AbstractBaz) where {T} = ^(something, getvalue(b))
       end
Main.Baz

```

So we have `Foo.foo`, `Bars.Bar` and `Baz.AbstractBaz` that don’t know each other, but all are accessible from `Main`. We can now subtype `AbstractBaz` with yet another type

```julia
julia> struct MyBaz <: Baz.AbstractBaz
           value::Int
       end

```

and we have to respect the interface of course

```julia
julia> Bars.bar[MyBaz(2)]
ERROR: The AbstractBaz interface demands that you define a specialized `getvalue(::MyBaz)` method.
Stacktrace:
 [1] error(s::String)
   @ Base .\error.jl:33
 [2] getvalue(b::MyBaz)
   @ Main.Baz .\REPL[3]:4
 [3] *(something::Int64, b::MyBaz)
   @ Main.Baz .\REPL[3]:5
 [4] getindex(#unused#::Main.Bars.Bar, ind::MyBaz)
   @ Main.Bars .\REPL[2]:4
 [5] top-level scope
   @ REPL[7]:1

julia> Baz.getvalue(b::MyBaz) = b.value

julia> Bars.bar[MyBaz(2)]
4.0

```

and then those things can work together seamlessly:

```julia
julia> Foo.foo(Bars.bar, MyBaz(3), [2,4,6])
176471.77731935095

```

Because when the compiler encounters `Foo.foo(::Bars.Bar, ::MyBaz, Vector{Int})` it can look up all the parts that make up foo and compose a specialized version of `foo` with those as long as they are accessible in Main.

---

<div class="post-metadata">

**Author:** ![lambdakappatheta](https://avatars.discourse-cdn.com/v4/letter/l/bbce88/32.png) [@lambdakappatheta](https://discourse.julialang.org/u/lambdakappatheta)\
**Post date:** [April 24, 2021, 1:09am UTC](https://discourse.julialang.org/t/multiple-dispatch-and-modules/59700/8 "2021-04-24T01:09:50Z")

</div>

Thank you all again for responding!

Let me explain my train of thougth step by step because I’m starting to think that I have made some false assumptions.

There are languages that allow developers to define functions inside of the definition of a type. Such functions are called methods.

> In class-based programming, methods are defined within a class, and objects are instances of a given class.  
> [Method (computer programming) - Wikipedia](https://en.wikipedia.org/wiki/Method_(computer_programming))

This is how a method is defined in Python (note that `f` is defined inside of `MyClass`):

```python
class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

```

Now, there is an obvious question: What are the advantages of defining a function inside a class?

The less important here is [encapsulation](https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)). In many languages, functions defined within a class are allowed to access the private fields of the class whereas functions defined elsewhere are not allowed to do so.

This is correct C++ code:

```cpp
class MyClass {
	private:
		int x = 0;
	public:
		int y = 0;

	void inc() {
		++x;
		++y;
	}
};

int main() {
	MyClass mc;
	mc.inc();
}

```

But the following doesn’t complie:

```cpp
class MyClass {
	private:
		int x = 0;
	public:
		int y = 0;
};

void inc(MyClass &mc) {
	++mc.x;
	++mc.y;
}

int main() {
	MyClass mc;
	inc(mc);
}

```

```julia
error: ‘int MyClass::x’ is private within this context

```

More importantly, if a function `f` is defined inside a class, then it lives inside the namespace of that class. See for instance: [Python Scopes and Namespaces](https://docs.python.org/3/tutorial/classes.html#a-word-about-names-and-objects). Let’s return to the previous Python example and look at how `f` is invoked:

```python
class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

mc = MyClass()

assert mc.f() == 'hello world'
assert MyClass.f(mc) == 'hello world'
#assert f(mc) == 'hello world'

```

Clearly, `f` can not only be invoked using method syntax `mc.f()` but also using function syntax `MyClass.f(mc)`. In this case, however, `f` needs to be prefixed with `MyClass` because that is the namespace it lives in. Try uncommenting the last line and see what happens.

This `mc.f()` syntax is important because it allows for dynamic dispatch. It, basically, says: Find `f` in the namespace of the type `mc` is an instance of and call `f` with `mc`. However, in Python, dynamic dispatch can also be achieved using the [`@singledispatch`](https://docs.python.org/3/library/functools.html#functools.singledispatch) annotation. Note how using `@singledispatch` does away with method syntax.

Encapsulation aside, since polymorphism can be achieved by means other than defining functions inside the body of a type (at least in Python which is enough for proof of concept, I think), why do people define functions within classes?

For me, the answer seems to be convenience and habit. In particular, as the author of a package, what do I do in class-based object-oriented languages? I, mentally, assign functions to types and implement those functions within the bodies of classes. And this is what my question is about! In Julia, a language where I cannot (and also do not want to) implement fuctions inside types, I seem to have a lot of freedom that I wasn’t exposed to before. By the way, I’ve realized that I would have a similar problem in C, even though C features neither multiple dispatch nor modules… hence the title 😀

Even within a single file, do I write this?

```c
struct A{};

struct B{}; 

struct C{};

void f() {}

void g(struct A a) {}
void h(struct B b) {}
void i(struct C c) {}

void j(struct A a, struct B b) {}
void k(struct A a, struct C c) {}
void l(struct B b, struct C c) {}

void m(struct A a, struct B b, struct C c) {}

```

or this?

```c
void f() {}

struct A{};

void g(struct A a) {}

struct B{}; 

void h(struct B b) {}

struct C{};

void i(struct C c) {}

void j(struct A a, struct B b) {}
void k(struct A a, struct C c) {}
void l(struct B b, struct C c) {}

void m(struct A a, struct B b, struct C c) {}

```

maybe this? (or something similar because of the missing forward declarations)

```c
void f() {}

struct A{};

void g(struct A a) {}
void j(struct A a, struct B b) {}
void k(struct A a, struct C c) {}
void m(struct A a, struct B b, struct C c) {}

struct B{}; 

void h(struct B b) {}
void l(struct B b, struct C c) {}

struct C{};

void i(struct C c) {}

```

I think, I, unconnsciously, came to the conclusion that a more powerful module system would make this question a no-brainer. Where do I define a function `f` that takes an `A`, a `B` and a `C`? Well, in the `'A-B-C'` module… And how do I find functions that take exacly an `A`, `B` and `C`? Well, I just bring `A`, `B` and `C` into scope and let the module system bring in `f` for me automatically.

But maybe it is imprtant to consider other factors and not to let the combination of types a function takes alone dictate its location…

One last thing I missed to acknowledge is that, as far as I see, functions defined within a class are the reason why it is easy to implement an online documentation like [cppreference.com](https://en.cppreference.com/w/) where I can search for a type and immediately see what actions can be performed on that type.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [April 24, 2021, 2:36am UTC](https://discourse.julialang.org/t/multiple-dispatch-and-modules/59700/9 "2021-04-24T02:36:48Z")

</div>

> [@lambdakappatheta](#):
>
> Encapsulation aside, since polymorphism can be achieved by means other than defining functions inside the body of a type (at least in Python which is enough for proof of concept, I think), why do people define functions within classes?

I often define methods on `MyFoo` class in order to ensure it conforms to the `AbstractFoo` interface. A formal interface makes it easy to ensure I’ve done it right. It’s possible to do this with dispatch too, but Julia doesn’t provide a standard way (yet?).
