I was asking about this feature on URLO (in a fashion: why this obvious idea is not implemented), but got no useful responses (except for reference to mysterious decisions-made-in-the-past-which-noone-name) thus I want to present it here as an idea.
I tried to look on IRLO and found this thread which ended with the following message: You must have something you want to use it for or you wouldn’t have brought it up, so would you mind posting some concrete examples where you think it would make the overall code clearer?
My idea is significantly limited form of what was proposed there: make it possible to call function which accepts a single tuple argument (or two arguments one of which is self, when it's called as foo.bar(…)
and not Foo::foo(bar, …)
with appropriate number of separate arguments if their number is not 1 (that is: if you call it like foo.bar()
then it becomes foo.bar(())
and foo.bar(1, 2)
then it can be interpreted as foo.bar((1, 2))
, but foo.bar(42)
would not become a foo.bar((42,))
.
This may sound like a useless syntax sugar, but can be used to make foreign JavaScript and C++ APIs much easier to use. Because currently used approach provides monstrosities like init_mouse_event_with_can_bubble_arg_and_cancelable_arg_and_view_arg_and_detail_arg_and_screen_x_arg_and_screen_y_arg_and_client_x_arg_and_client_y_arg_and_ctrl_key_arg_and_alt_key_arg_and_shift_key_arg_and_meta_key_arg_and_button_arg_and_related_target_arg.
How would this work? Just like official blog said few years ago: traits provide much of the benefit of overloading: if a method is defined generically over a trait, it can be called with any type implementing that trait.
You can do this in a stable Rust today, using traits:
let foo = Foo::new(());
foo.bar(());
let foo = Foo::new(24);
foo.bar(1);
let foo = Foo::new((1, 2));
foo.bar((0.2, 2));
That is: you can provide different overloads for a function or a method but when you need to pass number of arguments ≠ 1 then you have to wrap your arguments in a tuple.
Note that there are already one place in a language where compiler does that trick: Fn/FnMut/FnOnce traits. In fact on unstable Rust you can implement the syntax people would expect.
Now, you may say that function overloading is evil and one shouldn't use it, but the fact of the matter: it does exist. Many existing libraries and many existing platforms use it. If we can make use of these APIs closer to official documentation with examples in other languages then it would make overral code cleaner.
And if we only implement conversion from tuples to function arguments for a case where function accepts one argument and tuple have number elements other than one, then there should be no ambiguity because existing compiler would reject such code.
WDYT?