# Why Rust doesn't have function overloading?

**URL:** <https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416>\
**Category:** help\
**Created:** [August 27, 2022, 9:46am UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416 "2022-08-27T09:46:29Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Richyeoh](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/richyeoh/32/28762_2.png) [@Richyeoh](https://users.rust-lang.org/u/Richyeoh)\
**Post date:** [August 27, 2022, 9:46am UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/1 "2022-08-27T09:46:29Z")

</div>

Such as title. Why Rust doesn't have function overloading?

Some one code:

```rust
struct Serial{}

impl Serial{
    fn open(port:&str){}
    fn open(port:&str,baut:u32){}
}

```

Why?

---

<div class="post-metadata">

**Author:** ![H2CO3](https://avatars.discourse-cdn.com/v4/letter/h/b5ac83/32.png) [@H2CO3](https://users.rust-lang.org/u/H2CO3)\
**Post date:** [August 27, 2022, 10:00am UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/2 "2022-08-27T10:00:30Z")

</div>

Rust has a more general mechanism for achieving the same effects (and more) in a more uniform manner: traits and generics.

---

<div class="post-metadata">

**Author:** ![Richyeoh](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/richyeoh/32/28762_2.png) [@Richyeoh](https://users.rust-lang.org/u/Richyeoh)\
**Post date:** [August 27, 2022, 10:08am UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/3 "2022-08-27T10:08:07Z")

</div>

Do you have any information? I'll study.

---

<div class="post-metadata">

**Author:** ![Richyeoh](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/richyeoh/32/28762_2.png) [@Richyeoh](https://users.rust-lang.org/u/Richyeoh)\
**Post date:** [August 27, 2022, 10:16am UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/4 "2022-08-27T10:16:18Z")

</div>

Thks, I find official blog [Abstraction without overhead: traits in Rust | Rust Blog](https://blog.rust-lang.org/2015/05/11/traits.html)

---

<div class="post-metadata">

**Author:** ![kornel](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/kornel/32/4823_2.png) [@kornel](https://users.rust-lang.org/u/kornel)\
**Post date:** [August 27, 2022, 11:02am UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/5 "2022-08-27T11:02:41Z")

</div>

It doesn't. In this case the idiomatic solution would be a second method like:

```rust
fn open_with_baut(port:&str,baut:u32)

```

---

<div class="post-metadata">

**Author:** ![Richyeoh](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/richyeoh/32/28762_2.png) [@Richyeoh](https://users.rust-lang.org/u/Richyeoh)\
**Post date:** [August 27, 2022, 11:24am UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/6 "2022-08-27T11:24:14Z")

</div>

Yeah, I just be curious.

---

<div class="post-metadata">

**Author:** ![kornel](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/kornel/32/4823_2.png) [@kornel](https://users.rust-lang.org/u/kornel)\
**Post date:** [August 27, 2022, 11:33am UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/7 "2022-08-27T11:33:45Z")

</div>

Rust has type inference, so overloading of types of arguments of methods wouldn't work well. It could lead to surprising types being chosen, or just end up being ambiguous and require user to specify type hints.

There could be overloading based on the number of arguments, since that still allows type inference to look up the right method before knowing the types. In the internals forum you'll find a megathread discussing whether Rust should or should not have this:

> **[Pre-RFC: Named arguments](https://internals.rust-lang.org/t/pre-rfc-named-arguments/16413)**
>
> This is my first attempt at an RFC, any feedback is welcome :). I have read the previous topics and (except if I missed one) ensured there is not another open on the same subject right now. The most up-to-date version can be found at GitHub -...

---

<div class="post-metadata">

**Author:** ![SebastianJL](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/sebastianjl/32/26174_2.png) [@SebastianJL](https://users.rust-lang.org/u/SebastianJL)\
**Post date:** [August 27, 2022, 11:46am UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/8 "2022-08-27T11:46:04Z")

</div>

> [@Richyeoh](#):
>
> Thks, I find official blog [Abstraction without overhead: traits in Rust | Rust Blog](https://blog.rust-lang.org/2015/05/11/traits.html)

Does anyone know if there is an updated version of this blog post? It doesn't mention the dyn keyword for example.

---

<div class="post-metadata">

**Author:** ![VorfeedCanal](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/vorfeedcanal/32/22432_2.png) [@VorfeedCanal](https://users.rust-lang.org/u/VorfeedCanal)\
**Post date:** [August 27, 2022, 4:46pm UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/9 "2022-08-27T16:46:53Z")

</div>

> Rust has type inference, so overloading of types of arguments of methods wouldn't work well. It could lead to surprising types being chosen, or just end up being ambiguous and require user to specify type hints.

Yet this particular version of overloading is perfectly supported:

```rust
fn foo(x: impl core::fmt::Display) {
    print!("{x}\n")
}

fn main() {
    foo(1);
    foo(4.2);
    foo("Hello");
}

```

You need to first declare your function as “function with overloaded types” and then implement it separately, but it works.

> There could be overloading based on the number of arguments, since that still allows type inference to look up the right method before knowing the types.

And there actually **is** such overloading. [On nightly](https://docs.rs/overloadable/latest/overloadable/).

Which clearly shows that the decision not to support overloading is not technical but political. It's actually perfectly implementable and it's **actually implemented in the compiler**.

It's just not exposed to the users on stable. So… please don't try to justify it on technical grounds. It's just not fair.

---

<div class="post-metadata">

**Author:** ![Cerber-Ursi](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/cerber-ursi/32/8315_2.png) [@Cerber-Ursi](https://users.rust-lang.org/u/Cerber-Ursi)\
**Post date:** [August 27, 2022, 5:04pm UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/10 "2022-08-27T17:04:14Z")

</div>

It's not fair to accuse compiler developers of having a "political decision" of not stabilizing something they're not ready to stabilize, either.

---

<div class="post-metadata">

**Author:** ![jjpe](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/jjpe/32/28767_2.png) [@jjpe](https://users.rust-lang.org/u/jjpe)\
**Post date:** [August 27, 2022, 5:22pm UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/11 "2022-08-27T17:22:16Z")

</div>

> [@VorfeedCanal](#):
>
> Yet this particular version of overloading is perfectly supported:
> 
> ```rust
> fn foo(x: impl core::fmt::Display) {
> print!("{x}\n")
> }
> 
> fn main() {
> foo(1);
> foo(4.2);
> foo("Hello");
> }
> 
> ```

Despite the access pattern, this isn't overloading.

When a fn is overloaded (i.e. ad-hoc polymorphism is applied to it), it means that there are actually multiple fns with the same name that differ in their signatures. Among other things, this means that each fn in the overload group knows what type it accepts.

Contrast that to the above snippet. That's 1 fn, which accepts an `impl Trait` i.e. a specific-but-unknown type and does something with it based on `Trait`. It can't do anything else with it other than indicated by `Trait`¹, e.g. it can't access any fields or inherent methods.

So why does the snippet appear to work? Well, behind the screens the `foo` fn is monomorphized i.e. a version of `foo` is generated for one of the int types², one of the float types, and `&str`. Isn't that back to overloading then? Well, no, not entirely at least. That's because `foo` is still limited in what it can do with its argument.

¹ `Trait` here actually means "one or more traits", but that doesn't change the point above.  
² I'm not entirely sure what the inferred type of the `1` in `foo(1)` is. An obvious choice would be u8 to minimize space usage.

---

<div class="post-metadata">

**Author:** ![semicoleon](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/semicoleon/32/22313_2.png) [@semicoleon](https://users.rust-lang.org/u/semicoleon)\
**Post date:** [August 27, 2022, 5:30pm UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/12 "2022-08-27T17:30:15Z")

</div>

That crate uses a clever workaround to simulate function overloading by implementing the Fn\* traits for a struct. It isn't like nightly has a feature toggle that turns on function overloading.

---

<div class="post-metadata">

**Author:** ![VorfeedCanal](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/vorfeedcanal/32/22432_2.png) [@VorfeedCanal](https://users.rust-lang.org/u/VorfeedCanal)\
**Post date:** [August 27, 2022, 5:48pm UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/13 "2022-08-27T17:48:48Z")

</div>

> [@jjpe](#):
>
> Despite the access pattern, this isn't overloading.

Abstraction without overhead (which people already refered here) calls it overloading.

> [@jjpe](#):
>
> When a fn is overloaded (i.e. ad-hoc polymorphism is applied to it), it means that there are actually multiple fns with the same name that differ in their signatures.

Precisely the same happens here. Consider that [extended example](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=378141ec6cd55035f86048ab845d69df):

```rust
fn foo(x: impl Foo) {
    Foo::foo(x)
}

trait Foo {
    fn foo(self);
}

impl Foo for i32 {
    fn foo(self) {
        println!("This is int: {self}")
    }
}

impl Foo for f64 {
    fn foo(self) {
        println!("This is double: {self}")
    }
}

impl Foo for &str {
    fn foo(self) {
        println!("This is &str: {self}")
    }
}

fn main() {
    foo(1);
    foo(4.2);
    foo("Hello");
}

```

What limitation has this style of overloading may impose? Practically-speaking I can see only one: instead of writing `foo(1);`, `foo(1, 2);`, `foo(1, 2, 3);` you have to write `foo(1);`, `foo((1, 2));`, `foo((1, 2, 3));` (on stable, on nightly even that is fixable).

> [@semicoleon](#):
>
> It isn't like nightly has a feature toggle that turns on function overloading.

Yes, it has. For full-blown overloading you need this flexible conversion between single tuple and multi-argument function. That conversion is implemented in Rust, but only for special, “magical” traits `Fn`/`FnMut`/`FnOnce`.

And yes, it still leaves some plausible explanations for why it wouldn't be desirable to implement full-blown overloading (e.g. one may argue that supporting variadic templates would be better than supporting this automatic conversion for arbitrary function calls), but it shows that issues with overloading are political, not technical.

> [@Cerber-Ursi](#):
>
> It's not fair to accuse compiler developers of having a "political decision" of not stabilizing something they're not ready to stabilize, either.

It's not an accusation. Political does not “made by politics”. Joe Biden or Mister Putin are not the only ones who can do political decisions. There are [office politics](https://en.wikipedia.org/wiki/Office_politics), too.

The fact that they don't want to expose `Fn`/`FnMut`/`FnOnce` traits to stable Rust may be good or bad, but it's absolutely political decision, not technical one.

---

<div class="post-metadata">

**Author:** ![jjpe](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/jjpe/32/28767_2.png) [@jjpe](https://users.rust-lang.org/u/jjpe)\
**Post date:** [August 27, 2022, 6:04pm UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/14 "2022-08-27T18:04:03Z")

</div>

> [@VorfeedCanal](#):
>
> Abstraction without overhead (which people already refered here) calls it overloading.

That [isn't saying much](https://en.m.wikipedia.org/wiki/Argument_from_authority) unfortunately.

> [@VorfeedCanal](#):
>
> What limitation has this style of overloading may impose?

For all practical purposes, you just named it: you manually need to involve a trait, implement it for various types etc.  
Not impossible, but you don't get it automatically for free either.

But at that point, it's the `Foo` trait doing the polymorphism, not the `foo` fn. So while it can indeed be used to a similar effect, they're still different mechanisms.

> [@VorfeedCanal](#):
>
> It's not an accusation. Political does not “made by politics”. Joe Biden or Mister Putin are not the only ones who can do political decisions. There are [office politics](https://en.wikipedia.org/wiki/Office_politics), too.

My take on the words of @Cerber-Ursi was that when politics is named as a reason for something not happening, in general that has a negative connotation: that one or more stakeholders is either unwilling, or only willing for private gain.

Importantly, neither is the case here.  
If a feature isn't implemented, it's either due to an active decision on technical grounds, or it just hasn't been implemented because people both willing and able to work on rustc are relatively scarce.

> [@VorfeedCanal](#):
>
> The fact that they don't want to expose `Fn`/`FnMut`/`FnOnce` traits to stable Rust may be good or bad, but it's absolutely political decision, not technical one.

What are you basing that on? Who is unwilling, or trying to obtain personal gain in exchange for this feature?

---

<div class="post-metadata">

**Author:** ![geebee22](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/geebee22/32/16527_2.png) [@geebee22](https://users.rust-lang.org/u/geebee22)\
**Post date:** [August 27, 2022, 7:23pm UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/15 "2022-08-27T19:23:25Z")

</div>

The reason isn't technical, it could very likely be done, it is more that overloading is a dubious idea from a human point of view. For one thing, when you want to refer a human to a function, you cannot just name it, instead you have to name it and specify the types of the arguments.

So there is endless possible confusion. Another example, if you have a list of functions names being displayed in documentation as hyperlinks, unless the arguments are also shown, until you click on the link you don't know which function you are going to get.

In summary, it is "potentially confusing" and the language designers considered it to be a bad idea (for Rust), and that is also the general consensus.

---

<div class="post-metadata">

**Author:** ![Michael-F-Bryan](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/michael-f-bryan/32/28749_2.png) [@Michael-F-Bryan](https://users.rust-lang.org/u/Michael-F-Bryan)\
**Post date:** [August 27, 2022, 8:10pm UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/16 "2022-08-27T20:10:58Z")

</div>

> [@jjpe](#):
>
> What are you basing that on? Who is unwilling, or trying to obtain personal gain in exchange for this feature?

I think "political" is maybe not the right word here.

My understanding is they haven't stabilised `Fn` and friends because storing the arguments in a tuple means we'll be closing the door on variadic functions later on\[1\].

So it's a conscious decision made by humans for the sake of not accidentally painting ourselves into a corner later on.

* * *

1. Or at least making the implementation a lot harder. I don't think a debate on possible solutions/workarounds would be helpful here.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/scottmcm/32/4286_2.png) [@scottmcm](https://users.rust-lang.org/u/scottmcm)\
**Post date:** [August 27, 2022, 8:30pm UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/17 "2022-08-27T20:30:27Z")

</div>

> [@Richyeoh](#):
>
> Why Rust doesn't have function overloading?

What rust doesn't have is _ad-hoc_ overloading. It has _principled_ overloading via traits instead -- that's how `+` can work on lots of types, for example.

It chose this because ad-hoc overloading doesn't mix well with type inference and generic code, whereas traits work great with both.

The pattern in Rust to do what your example looks like it's going for is "options" classes, like [OpenOptions in std::fs - Rust](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html).

---

<div class="post-metadata">

**Author:** ![jwarlander](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/jwarlander/32/25417_2.png) [@jwarlander](https://users.rust-lang.org/u/jwarlander)\
**Post date:** [August 28, 2022, 1:21pm UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/18 "2022-08-28T13:21:52Z")

</div>

I've found overloading on the number of arguments to be a reasonable approach; I guess we'll see what happens on that front, as it seems to be under evaluation already..

Even so, in eg. Erlang, where this routinely happens, you generally refer to functions like `foo/1`, `foo/2` etc, indicating the number of arguments.

---

<div class="post-metadata">

**Author:** ![m51](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/m51/32/25834_2.png) [@m51](https://users.rust-lang.org/u/m51)\
**Post date:** [August 28, 2022, 3:52pm UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/19 "2022-08-28T15:52:06Z")

</div>

> [@jwarlander](#):
>
> I've found overloading on the number of arguments to be a reasonable approach; I guess we'll see what happens on that front, as it seems to be under evaluation already..

It depends. In C#, overloading based on number and type of arguments sometimes interacts in very surprising ways with optional, default-valued, and named arguments.

I'm quite happy with Rust's explicit appoach.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/scottmcm/32/4286_2.png) [@scottmcm](https://users.rust-lang.org/u/scottmcm)\
**Post date:** [August 28, 2022, 9:24pm UTC](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416/20 "2022-08-28T21:24:37Z")

</div>

> [@m51](#):
>
> In C#, overloading based on number and type of arguments sometimes interacts in very surprising ways with optional, default-valued, and named arguments.

One piece this reminded me to emphasize: When you have overloading on types, you need _overload resolution_ rules. These are by no means easy to get right, as Microsoft indirectly admits:

> The overload resolution rules have been updated in nearly every C# language update to improve the experience for programmers, making ambiguous invocations select the "obvious" choice.
> 
> ~ [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-7.3/improved-overload-candidates](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-7.3/improved-overload-candidates)

(Those are their own scare quotes! I didn't add them.)

Since Rust has traits, Rust needs to have _trait_ resolution rules, which are also non-trivial. (See the work [around chalk](https://smallcultfollowing.com/babysteps/blog/2017/01/26/lowering-rust-traits-to-logic/), for example.)

It would be a nightmare -- both for programmers and for the language designers -- to have both complex overload resolution rules _and_ complex trait resolution rules. Worse, if they needed to interact -- perhaps because of `dyn Trait` and `impl Trait` parameters -- it could get particularly ugly.

So since, as I previously mentioned, ad-hoc overloading mixes poorly with generic code and thus traits are needed anyway, Rust would rather just have the one mechanism for this kind of "choose the thing to call based on types" desire.

And thus, for example, `Vec::extend` is a trait that's implemented twice ([https://doc.rust-lang.org/std/vec/struct.Vec.html#impl-Extend\<%26'a%20T\>](https://doc.rust-lang.org/std/vec/struct.Vec.html#impl-Extend%3C%26%27a%20T%3E)), not a function with two different overrides.

[Next page](https://users.rust-lang.org/t/why-rust-doesnt-have-function-overloading/80416.md?page=2)
