Overloading
Type Overloading
Overloading is convenient. It allows one method to be used for different types, as in Java's PrintStream.println()
:
void println(boolean b) void println(char c) void println(char[] s) void println(double d) void println(float f) void println(int i) void println(long l) void println(Object obj) void println(String s)
Disadvantages of overloading include
- Code duplication, e.g., Java's PrintStream.println() implementation is essentially the same code repeated 9 times.
- Ambiguity: In particular in combination with (multiple) inheritance and multiple arguments, it becomes non-obvious which variant will be called.
- Maintainability: In case an overloaded method is redefined in a sub-class, adding one variant in the super-class is a change that can easily be overlooked in the sub-class.
An alternative to overloading that avoids these disadvantages might be choice types:
println(x bool | char | Array char | f64 | f32 | i32 | i64 | String | Object) is match x b bool => print_string (b ? "true" : "false") c char => print_char c a Array char => a | (c) -> print_char c f f64 => print_f64 f f f32 => print_f32 f i i64 => print_f64 i i i32 => print_f32 i s String => print_string s o Object => print_string "Some Object" print LF
This avoids the duplication and ambiguity. It should also improve maintainability since the match statement should flag missing cases. Open questions
- should it be allowed to add more choices in a redefinition? Is this feature worth the added complexity?
- do we need an easier choice syntax, e.g.
println(x bool | char | Array char | f64 | f32 | i32 | i64 | String | Object) is
Argument Count Overloading
Overloading features with different argument counts is much easier than overloading with different types. Usually, the argument count is obvious.
Nevertheless, argument count overloading is complicated in Fuzion as follows.
- Since Fuzion features define a type, two features with the same name but different argument counts would define two types that cannot be distinguished syntactically when using the name only to specify a type
- Open generic arguments allow sub-classes to change the actual number of arguments depending on the actual generic arguments. Furthermore, the actual generic arguments might not be given explicitly, but might be the result of type inference.
Possible solutions:
Type declarations
A simple solution is just to forbid the use of features as type name in case there is overloading.
Alternatively, type syntax could be extended by an optional argument count
parameters to resolve ambiguity: v t[3]
to declare
field v
to be of the variant of type t
with three
arguments.
Open Generics
Again, overloading could be forbidden in cases where open generics would cause ambiguity.
Alternatively, the compiler front-end could be enhanced to handle it since eventually the actual number of arguments must be known after type inference.