# Claim (false): Julia isn't multiple dispatch but overloading

**URL:** <https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370>\
**Category:** General Usage\
**Tags:** multidispatch\
**Created:** [July 1, 2020, 1:55pm UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370 "2020-07-01T13:55:00Z")\
**Posts on this page:** 16\
**Page:** 7

<div class="post-metadata">

**Author:** ![Liso](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@Liso](https://discourse.julialang.org/u/Liso)\
**Post date:** [August 17, 2021, 7:58pm UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370/122 "2021-08-17T19:58:07Z")

</div>

> [@bgroenks](#):
>
> However, this is still not enough. In order to accomplish similar behavior with static overloading, we would need concrete overloads for each special type, e.g:
> 
> ```julia
> ols(x::AbstractVector{T}, y::AbstractVector{T}) where {T} = ...
> ols(x::AbstractMatrix{T}, y::AbstractVector{T}) where {T} = ...
> 
> ```

You could write universal function in statically typed C++ too:

```cpp
#include <iostream>

// you define fnc once i.e. you don't need to specialize it for every type
template <typename A, typename B>
void fnc(A a, B b){ std::cout << (a + b) << std::endl; }

// you could use any object that support + operator and << operator (with std::cout)
struct C{
  std::string s;
  C operator+(C b){ return C{s+b.s}; }
};
std::ostream& operator <<(std::ostream& io, const C& c){ io << c.s; return io; }

int main(){
        fnc(1, 1);
        fnc(1.1, 1.1);
        fnc(C{"hello "}, C{"world"});
}

```

Output:

```julia
2
2.2
hello world

```

I don’t say that C++ is as flexible and expressible as Julia.  
I am just afraid that accepted answer contains _false claim_.

---

<div class="post-metadata">

**Author:** ![bgroenks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bgroenks/32/21784_2.png) [@bgroenks](https://discourse.julialang.org/u/bgroenks)\
**Post date:** [August 18, 2021, 4:03pm UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370/123 "2021-08-18T16:03:43Z")

</div>

I did not say that it was not possible to achieve this in other ways in C++. I said it was prohibitively difficult to do it with **overloading** alone. Of course one could certainly use generic programming (in C++, templates) to accomplish something similar, although this comes with a whole range of issues that are out of scope of this discussion.

---

<div class="post-metadata">

**Author:** ![Liso](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@Liso](https://discourse.julialang.org/u/Liso)\
**Post date:** [August 18, 2021, 4:56pm UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370/124 "2021-08-18T16:56:41Z")

</div>

I am just curious. How would you call that _something similar_?

Is it overloading or not? Is it multiple dispatch or not?

And why?

---

<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:** [August 18, 2021, 5:28pm UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370/125 "2021-08-18T17:28:49Z")

</div>

> [@Liso](#):
>
> How would you call that _something similar_ ?
> 
> Is it overloading or not? Is it multiple dispatch or not?

clearly you could achieve static overloading with static overloading alone, it’s the late binding that is hard to achieve:

> [@bgroenks](#):
>
> with static overloading

* * *

As you probably already know, template gets obscure and hard to extend very quickly once the usage stops being “literally copy-pasting the same function body for every possible type”.

---

<div class="post-metadata">

**Author:** ![bgroenks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bgroenks/32/21784_2.png) [@bgroenks](https://discourse.julialang.org/u/bgroenks)\
**Post date:** [August 19, 2021, 2:39pm UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370/126 "2021-08-19T14:39:32Z")

</div>

No, templates and generic types are not multiple dispatch. However, they can be seen as a static type solution to one of the problems I described, namely the redundancy of defining functions for multiple types.

As @jling pointed out, C++ templates are pretty much literally just syntactic sugar for copy-pasta. This can imitate a limited form of multiple dispatch by simply auto-generating static overloads for functions, assuming that all of the relevant types are _known at compile time_. However, it’s not “true” multiple dispatch in the sense that (1) it happens at compile time (early binding) and (2) it’s not polymorphic. In order to use polymorphism in C++, you need classes/objects, which only support single dispatch.

If you want to continue discussing the differences between C++ and Julia, I would suggest starting a new topic on the issue.

---

<div class="post-metadata">

**Author:** ![Liso](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@Liso](https://discourse.julialang.org/u/Liso)\
**Post date:** [August 19, 2021, 5:17pm UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370/127 "2021-08-19T17:17:47Z")

</div>

Saying _ **just** syntactic sugar_ is … questionable. You could similarly say that higher level programmer language is just syntactic sugar for assembler or machine code.

* * *

You say that “true” dispatch need to be polymorphic. But … :

> [@StefanKarpinski](#):
>
> However, that disagrees with what people in the industry would call this: the non-virtual one is static dispatch (aka “early binding”) and the virtual one is dynamic dispatch (aka “late binding”).

It seems that you and Stefan are using term `dispatch` differently. Or is Stefan talking about “untrue” dispatch?

* * *

No I didn’t want to discuss about differences between C++ and Julia. I just felt some thing are not properly “solved” and some terms were used in “non stable” meaning.

But I am not interested to dig deeper if there is no mutual interest to improve understanding.

* * *

It was really interesting topic! 🙂

For me - this is the best answer to @dataSurfer’s original question in this topic:

> [@StefanKarpinski](#):
>
> In Julia there is only dynamic dispatch: there is no way to ask for static (non-virtual) dispatch behavior—it is all dynamic, all the time, on all of the arguments. There isn’t even a concept a static type by which one might statically select a method in principle.

This POV surprised me. But if you think about it it feels like it Julia really is. (and it could be good for some kinds of problem and wrong for other kinds)

I also liked @dataSurfer `@code_warntype` example and @tim.holy’s `@code_llvm` one.

But this surprised me too: Julia use [C infrastructure](https://github.com/JuliaLang/julia/blob/5453b6a46eac30ead07ae9fe059bceba658ea964/src/gf.c#L2420) to achieve multiple dispatch. 😮  
🙂

---

<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:** [August 19, 2021, 5:29pm UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370/128 "2021-08-19T17:29:16Z")

</div>

> [@Liso](#):
>
> You could similarly say that higher level programmer language is just syntactic sugar for assembler or machine code.

no one would object the technically true statement that you can write everything with machine code. But it’s always about:

> [@bgroenks](#):
>
> prohibitively difficult

Saying “C/C++ can achieve everything Julia can because zero-cost abstraction, QED” is not useful, because possibility != people write useful, maintainable, extendable software with the hypothetical pattern. The reality is simply that, common pattern in C/C++ doesn’t give you what multi patch gives you and more importantly, they behave differently.

As you have observed:

> [@Liso](#):
>
> to achieve multiple dispatch.

Languages that uses LLVM as their compiler doesn’t mean these languages are basically C++. Rust is not C++, Python is not C. What being used to implement compiler is almost not relevant at all.

---

<div class="post-metadata">

**Author:** ![Liso](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@Liso](https://discourse.julialang.org/u/Liso)\
**Post date:** [August 19, 2021, 6:55pm UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370/129 "2021-08-19T18:55:40Z")

</div>

> [@jling](#):
>
> Saying “C/C++ can achieve everything Julia can because zero-cost abstraction, QED” is not useful,

And I fully agree with you.  
There are many things you could simply express in Julia and you have difficulties to achieve in C++. I will not argue here.  
It is why I argue that syntactic sugar is good and important thing.

> [@jling](#):
>
> Languages that uses LLVM as their compiler doesn’t mean these languages are basically C++. Rust is not C++, Python is not C. What being used to implement compiler is almost not relevant at all.

Maybe I am wrong but I think that code in gf.c is compiled, linked and used in runtime and not just during compile phase.

---

<div class="post-metadata">

**Author:** ![bgroenks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bgroenks/32/21784_2.png) [@bgroenks](https://discourse.julialang.org/u/bgroenks)\
**Post date:** [August 19, 2021, 7:10pm UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370/130 "2021-08-19T19:10:09Z")

</div>

> [@Liso](#):
>
> Saying _ **just** syntactic sugar_ is … questionable. You could similarly say that higher level programmer language is just syntactic sugar for assembler or machine code.

No, this is not the same thing. Templates implicitly generate _code in the same language_ (C++), while here you are referring to the process of compilation or machine translation. Syntactic sugar != compilation.

> [@Liso](#):
>
> It seems that you and Stefan are using term `dispatch` differently. Or is Stefan talking about “untrue” dispatch?

No, we aren’t. @StefanKarpinski and I are referring to the same thing. The `virtual` keyword induces polymorphism, i.e. it states “this method can be overridden and invoked dynamically on subtypes”. In single dispatch, this invocation is determined by the (implicit) first argument.

> [@Liso](#):
>
> This POV surprised me. But if you think about it it feels like it Julia really is.

This was the point of my entire paragraph on why “compile-time” in Julia means something entirely different than in C/C++, Java, etc. Julia is inherently dynamic, all the way through. The compiler + LLVM is just a clever way to recover the performance typically lost in dynamic code interpretation.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [August 20, 2021, 3:34pm UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370/131 "2021-08-20T15:34:05Z")

</div>

9 posts were split to a new topic: [OLS: difference between \ and inv (in normal equation)](https://discourse.julialang.org/t/ols-difference-between-and-inv-in-normal-equation/66739)

---

<div class="post-metadata">

**Author:** ![gbellomia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbellomia/32/19443_2.png) [@gbellomia](https://discourse.julialang.org/u/gbellomia)\
**Post date:** [September 23, 2022, 1:02am UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370/132 "2022-09-23T01:02:04Z")

</div>

I think future visitors of the page may want to read this:

> [@Allocation and slow down when # of types involved increase (slower than C++ virtual methods)](https://discourse.julialang.org/t/allocation-and-slow-down-when-of-types-involved-increase-slower-than-c-virtual-methods/87656/3):
>
> Dynamic dispatch is slow in Julia — slower than C++ virtual methods, because C++ method dispatch only depends on a single object type (this) and hence can use [vtable](https://en.wikipedia.org/wiki/Virtual_method_table) lookup. High-performance code in Julia always relies on devirtualizing critical code. This also means that you can’t easily write performant geometry code in Julia by having an array of geometric objects of different types and relying on dynamic dispatch to execute different methods (determined at runtime) for different objects —…

Reason is in my honest opinion the true sentiment of the original claim and the push force of frequent recurrent revival is that: yes, Julia semantics are inherently dynamic but everytime you need performance (which is a very strong selling point for the language), you need to make sure the actual behavior can be devirtualized, effectively reconciling with static overloading.

Ideally I would post this even under the celebrated YouTube video (The unreasonable…), but YouTube has no good facilities for screenshot embedding or nice external link rendering 🙂

---

<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:** [September 23, 2022, 1:26am UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370/133 "2022-09-23T01:26:49Z")

</div>

> [@gbellomia](#):
>
> you need to make sure the actual behavior can be devirtualized, effectively reconciling with static overloading.

No, devirtualization is not the same as static overloading. Static overloading is determined by the types declared at the method-definition site, but devirtualization occurs based on the types inferred at the _call_ site.

---

<div class="post-metadata">

**Author:** ![gbellomia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbellomia/32/19443_2.png) [@gbellomia](https://discourse.julialang.org/u/gbellomia)\
**Post date:** [September 23, 2022, 1:27am UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370/134 "2022-09-23T01:27:41Z")

</div>

Thanks for the clarification (this\* is rather technical and subtle to me, but I see your point) 🙂

\*what is actually obscure to me at this point is how devirtualization is different from call-site inference and why the latter is faster (but this amount to me knowning what devirtualization really is…)

---

<div class="post-metadata">

**Author:** ![jsjie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jsjie/32/22477_2.png) [@jsjie](https://discourse.julialang.org/u/jsjie)\
**Post date:** [May 20, 2024, 4:38am UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370/135 "2024-05-20T04:38:00Z")

</div>

Sorry for a late reply, but I’m afraid that you may be wrong. The problem (in fact the post itself has a similar problem) is the insufficient understanding of [polymorphism](https://en.wikipedia.org/wiki/Polymorphism_(computer_science)). Let me put it simple:

1. There are many types of polymorphism. Most notably, ad hoc polymorphism (function overloading), parametric polymorphism (can be achieved by templates) and subtyping (multiple dispatch in Julia, single dispatch through function overriding in C++).
2. The post made the error that it didn’t differentiate ad hoc polymorphism from subtyping.
3. bgroenks correctly described how these two are different.
4. You made the error that you didn’t differentiate parametric polymorphism from ad hoc polymorphism (they are both compile-time polymorphism).

Even simpler:

1. Static loading is definitely **not** the same thing as static type solution. The former only contains ad hoc polymorphism, while the latter also contains parametric polymorphism, as templates you have mentioned.
2. The post is about the difference between static loading and multiple dispatch, it certainly has nothing to do with templates.
3. bgroenks correctly described how static **loading** and multiple dispatch are different. There are no false claims.

Besides, some languages, most notably C++, have their own definition of polymorphism, which is usually a subset of the polymorphism described above. But I believe it will be beneficial to have a gerenal understanding.

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/224680_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [May 20, 2024, 1:27pm UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370/136 "2024-05-20T13:27:02Z")

</div>

This discussion was already fairly long and dates back to 2022, closing the thread now. Feel free to open more new topics though.

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/224680_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [May 20, 2024, 1:27pm UTC](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370/137 "2024-05-20T13:27:07Z")

</div>



[Previous page](https://discourse.julialang.org/t/claim-false-julia-isnt-multiple-dispatch-but-overloading/42370.md?page=6)
