# Understanding multiple dispatch

**URL:** <https://discourse.julialang.org/t/understanding-multiple-dispatch/76601>\
**Category:** General Usage\
**Tags:** python, multidispatch\
**Created:** [February 17, 2022, 3:13am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601 "2022-02-17T03:13:44Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![how](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/how/32/33879_2.png) [@how](https://discourse.julialang.org/u/how)\
**Post date:** [February 17, 2022, 3:13am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/1 "2022-02-17T03:13:45Z")

</div>

Hi, I am studying Multiple dispatch, and have some troubles.

While studying Julia language, I understood that

Multiple dispatch is something that selecting which method to be applied based on the argument’s type.

In that sense, I understood that even the simple “+” function of Julia has multiple methods and we are using multiple dispatch concepts naturally. (I guess [Julia document](https://docs.julialang.org/en/v1/manual/methods/#Methods) also said like this.)

However, as far as i know, the same thing can be applied in Python too in terms of this + function.

Python also be able to calculate 1+1 and 1.0 + 1.0 with the same function, +. (Of course, string + string also works)

Then, can we say that Python is also using multiple dispatch?

I am curious because I read that Python is not able to implement multiple dispatch.

Thanks.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [February 17, 2022, 3:15am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/2 "2022-02-17T03:15:35Z")

</div>

> [@how](#):
>
> Python too in terms of this + function.

python has ` __add__ ()` and friends to implement what’s called “operator overloading”, it is not multiple dispatch.

Python people also sometimes do a lot of manual dispatch:

```julia
self. __add__ (self, y):
   if isinstance(y, type1):
     ...
   elif isinstance(y, type2):
     ...

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [February 17, 2022, 3:33am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/3 "2022-02-17T03:33:00Z")

</div>

> [@how](#):
>
> Python also be able to calculate 1+1 and 1.0 + 1.0 with the same function, +. (Of course, string + string also works)

Actually, Python needs two different functions to simulate multiple dispatch (dispatch on both arguments of `+`), and it only works for a few “magic” functions. This is discussed in @jeff.bezanson’s [PhD thesis](https://github.com/JeffBezanson/phdthesis/blob/master/main.pdf):

> Numbers tend to be among the most complex features of a language. Numeric types usually need to be a special case: in a typical language with built-in numeric types, describing their behavior is beyond the expressive power of the language itself. For example, in C arithmetic operators like `+` accept multiple types of arguments (ints and floats), but no user-defined C function can do this (the situation is of course improved in C++). **In Python, a special arrangement is made for `+` to call either an ` __add__ ` or ` __radd__ ` method, effectively providing double-dispatch for arithmetic in a language that is idiomatically single-dispatch.**

In general, Python functions are only “single-dispatch” — when you call `obj.method(args...)`, it only looks at the type of `obj`. Python provides a somewhat crude form of double dispatch for overloading a few binary operators like `+` and `*`, but does this by requiring you to implement _two_ “magic methods” (such as ` __add__ ` and ` __radd__ `) in general.

---

<div class="post-metadata">

**Author:** ![johnh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnh/32/3615_2.png) [@johnh](https://discourse.julialang.org/u/johnh)\
**Post date:** [February 17, 2022, 3:35am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/4 "2022-02-17T03:35:10Z")

</div>

In one Julia tutorial I saw the @code\_llvm macro is used to show what code is emitted by Julia for a simple function. You can see how multiple dispatch emits code for each type of the arguments.  
Please - if anyone can give a link to this tutorial I would be grateful.

ps. It may have been @code\_native

---

<div class="post-metadata">

**Author:** ![johnh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnh/32/3615_2.png) [@johnh](https://discourse.julialang.org/u/johnh)\
**Post date:** [February 17, 2022, 3:39am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/5 "2022-02-17T03:39:11Z")

</div>

Aha. The tutorial is the Unreasonable Effectiveness of Multiple Dispatch

Julia is also composable. I love the example with measurements / error bars here at 3:30

[![](https://global.discourse-cdn.com/julialang/original/3X/c/5/c5a2f02c81c376da005f8610ce9cdd4ad47cfdf4.jpeg "JuliaCon 2019 | The Unreasonable Effectiveness of Multiple Dispatch | Stefan Karpinski") ](https://www.youtube.com/watch?v=kc9HwsxE1OY)

---

<div class="post-metadata">

**Author:** ![how](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/how/32/33879_2.png) [@how](https://discourse.julialang.org/u/how)\
**Post date:** [February 17, 2022, 4:31am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/6 "2022-02-17T04:31:41Z")

</div>

> [@jling](#):
>
> operator overloading

Thanks, Python is using overloading not a multiple dispatch!

---

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [February 17, 2022, 7:20am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/7 "2022-02-17T07:20:25Z")

</div>

For me the confusion comes from where to apply the term “multiple”.  
It does not mean that there are multiple methods, but that they are chosen depending on the types of one or more arguments.

---

<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:** [February 17, 2022, 7:24am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/8 "2022-02-17T07:24:29Z")

</div>

It’s dispatch on _multiple_ arguments. Unlike other languages that only use a _single_ argument to choose a method.

---

<div class="post-metadata">

**Author:** ![how](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/how/32/33879_2.png) [@how](https://discourse.julialang.org/u/how)\
**Post date:** [February 17, 2022, 7:35am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/9 "2022-02-17T07:35:44Z")

</div>

Here what is the exact meaning of multiple arguments?

for example, let’s say

f(a::Int64, b::Int64) = 2x + y  
f(a::Float64, b::Float64) = 2x-y

then here are two arguments of pairs, (Int64, Int64) and (Float64, Float64) right?

And the meaning of Multiple dispatch is that it can choose which method is more appropriate for the user’s input argument right?

Thanks.

---

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [February 17, 2022, 8:12am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/10 "2022-02-17T08:12:09Z")

</div>

Yes, you can see in the REPL:

```julia
julia> f(a::Int64, b::Int64) = 2x + y
f (generic function with 1 method)

julia> f(a::Float64, b::Float64) = 2x-y
f (generic function with 2 methods)

julia> @which f(1,1)
f(a::Int64, b::Int64) in Main at REPL[1]:1

julia> @which f(1.0,1.0)
f(a::Float64, b::Float64) in Main at REPL[2]:1

```

Make sure to read [Performance Tips · The Julia Language](https://docs.julialang.org/en/v1.7.2/manual/performance-tips/)

---

<div class="post-metadata">

**Author:** ![how](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/how/32/33879_2.png) [@how](https://discourse.julialang.org/u/how)\
**Post date:** [February 17, 2022, 8:18am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/11 "2022-02-17T08:18:15Z")

</div>

I see the points.

So, in case of the Python, your code only works for (a::Float64, b::Float64), not for the previous code with (a::Int64, b::Int64).

and this would indicate that Python only use a single argument unlike Julia.

---

<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:** [February 17, 2022, 8:33am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/12 "2022-02-17T08:33:46Z")

</div>

I’m not sure you mean the right thing here.

Python can only do essentially `f(a::Int64, b)` and `f(a::Float64, b)` , i.e. it can’t take _both_ arguments’ types into account when choosing a method.

---

<div class="post-metadata">

**Author:** ![how](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/how/32/33879_2.png) [@how](https://discourse.julialang.org/u/how)\
**Post date:** [February 17, 2022, 8:43am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/13 "2022-02-17T08:43:52Z")

</div>

Sorry for asking u again,

but when user defines his own functions in Python, he can make multiple arguments(Below example, multiple arguments are ‘a’ and ‘b’) as input parameters and also is able to set both types. For example,

```julia
def f(a:int, b:int):
    return(a+b)

f(1.0, 2)
# 3.0

```

I used 1.0 as an input parameter which is not an _int_ type, but still got an answer.  
It shows that python does not care about the type unlike Julia anyway.

What do you mean that Python can only do the first arguments’ types into account?

Thanks.

---

<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:** [February 17, 2022, 9:01am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/14 "2022-02-17T09:01:08Z")

</div>

So, I’m not very good at Python, but from what I understand you can have multiple methods of the same function if you create them as “instance methods”. So `foo.bar(baz)` chooses a method based on the type of `foo`. In Julia, this would be `bar(foo, baz)`, and you can have different methods depending on the types of both `foo` and `baz`.

---

<div class="post-metadata">

**Author:** ![lawless-m](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lawless-m/32/30869_2.png) [@lawless-m](https://discourse.julialang.org/u/lawless-m)\
**Post date:** [February 17, 2022, 9:03am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/15 "2022-02-17T09:03:55Z")

</div>

```julia
matt@pox:~$ python3                                                      
Python 3.9.2 (default, Feb 28 2021, 17:03:44)                            
[GCC 10.2.1 20210110] on linux                                           
Type "help", "copyright", "credits" or "license" for more information.   
>>> def f(a:int, b:int) :                                                
... return (a+b)                                                      
...                                                                      
>>> def f(a:int, b:str) :                                                
... return str(a) + b                                                  
...                                                                      
>>>                                                                      
>>> def f(a:str, b:str) :                                                
... return a+b                                                         
...                                                                      
>>> f(1,2)                                                               
3                                                                        
>>> f(1, "a")                                                            
Traceback (most recent call last):                                       
  File "<stdin>", line 1, in <module>                                    
  File "<stdin>", line 2, in f                                           
TypeError: unsupported operand type(s) for +: 'int' and 'str'            
>>> f("a", "b")                                                          
'ab'                                                                     

```

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [February 17, 2022, 9:11am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/16 "2022-02-17T09:11:18Z")

</div>

> [@how](#):
>
> So, in case of the Python, your code only works for (a::Float64, b::Float64), not for the previous code with (a::Int64, b::Int64).

It goes perhaps without saying that you can’t add methods for a custom `f` function in Python for the standard `int` and `float` classes, because classes in Python are closed.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [February 17, 2022, 9:38am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/17 "2022-02-17T09:38:20Z")

</div>

> [@how](#):
>
> I read that Python is not able to implement multiple dispatch.

It is possible to get multiple dispatch in Python: [multipledispatch · PyPI](https://pypi.org/project/multipledispatch/)

I don’t know how well it works. But the things that make multiple dispatch great in Julia are that it is used _everywhere_, and that it is _fast_, so there’s no performance penalty for using it. I don’t know how efficient the python implementation is, but MD is certainly not going to be pervasive in Python for a long time, if ever.

---

<div class="post-metadata">

**Author:** ![paulmelis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paulmelis/32/35063_2.png) [@paulmelis](https://discourse.julialang.org/u/paulmelis)\
**Post date:** [February 17, 2022, 10:37am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/18 "2022-02-17T10:37:16Z")

</div>

> [@how](#):
>
> I used 1.0 as an input parameter which is not an _int_ type, but still got an answer.  
> It shows that python does not care about the type unlike Julia anyway.

Type annotations in Python are purely for the user. The (standard) Python interpreter doesn’t use them, only special tools like mypy do

---

<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:** [February 17, 2022, 1:53pm UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/19 "2022-02-17T13:53:44Z")

</div>

I really suggest editing out the medium article, it completely misses the point of what makes multiple dispatch “multiple” and shows only single-argument examples. If I did not know Julia and wanted to defend the use of Python in my lab/office, I would use it as a prime example of Julia people do not knowing of what they talk about.

---

<div class="post-metadata">

**Author:** ![how](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/how/32/33879_2.png) [@how](https://discourse.julialang.org/u/how)\
**Post date:** [February 21, 2022, 2:24am UTC](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601/20 "2022-02-21T02:24:24Z")

</div>

Excuse me, but I read [the article](https://medium.com/swlh/how-julia-uses-multiple-dispatch-to-beat-python-8fab888bb4d8) u are pointing out a few days ago, and I did not realize what’s going wrong with the examples in the article.

Could you explain a bit more about what points the article missed about **the real meaning of “multiple dispatch”**?

In the article, it shows below codes as an example

```julia
f(x::Int64) = x^2 % 4
f(x::Float64) = f(ceil(Int64, x))
f(x::String) = f(parse(Float64, x))

```

and I thought this as a simple and nice example of showing multiple dispatch of Julia, since three (which is multiple) arguments (Int64, Float64, String) are available onto the same function, f.

and the codes shows below result, which made me think the article fits well with this discussion.

```julia
f (generic function with 3 methods)

```

Thanks.

[Next page](https://discourse.julialang.org/t/understanding-multiple-dispatch/76601.md?page=2)
