Function overloads are declared like in C++, simply by redeclaring a function with the same name and different parameters.
Function overloads are stored in overload sets. Like many things in goose, overloadsets are values that can be passed around as such.
All matching overloads for a call are given a score that is designed to favor more specific matches over more generic matches.
So if a function foo have two overloads
void foo( int a ) void foo( $T a )
Calling foo(123) will call the first overload.
Likewise with template functions, the templates with fewer distinct named template variables is favored.
void foo( $T a, $U b ) void foo( $T a, $T b )
Calling foo( 123, 456 ) will call the second overload because both types are identical, which is a more specific signature than the other.