// overloading on return type
func random() -> Int { 3; }
func random() -> String { "abc"; }
func random() -> Double { 3.5; }
var r1 : Int = random();
print( r1 );
var r2 : String = random();
print( r2 );
var r3 : Double = random();
print( r3 );

// function overloading without parameter names
//func fun( _ x : Int ) { 3; }
//func fun( _ x : Int, _ y : Int ) { 3; }
func fun( _ x : Double ) { 3; }
func fun( _ x : Int ) -> Int { 3; }
func fun( _ x : Int, _ y : Int ) -> Int { x + y; }
func fun( _ x : String ) -> String { "abc"; }
print( fun( 3, 4 ) );
// print( fun( 3.5 ) ); // no Double -> Int
//print( fun( r3 ) ); // no, Double -> Int

// overloading on parameter name
func foo( x : Int ) -> Int { 3; }
func foo( y : Int ) -> Int { 3; }
print( foo( x : 3 ) );
print( foo( y : 3 ) );

// overloading on member name
class C {
    func foo() {}
    func foo( _ x: Int ) -> Int { 3; }
    func foo( _ x : Double, _ y : Double ) -> Double { x + y; }
    func foo( _ x : String ) -> String { "abc"; }
}

let c = C()
c.foo();
r1 = c.foo( 3 );
r3 = c.foo( 3, 3.5 );
r2 = c.foo( "abc" );

// generic overloading without parameter names
func bar<T>( _ a : T ) { print( "bar1", a ); }
func bar<T>( _ a : T, _ b : T ) { print( "bar2", a, b ); }
func bar<T,U>( _ a : T, _ b :  U) { print( "bar3", a, b ); }
bar( 3 );
bar( 3.5 );
bar( 2, 2 );
bar( 2, 2.5 );

// generic overloading with parameter names
func baz( a : Int ) { print( "baz1", a ); }
func baz<T>( a : T ) { print( "baz1", a ); }
func baz<T>( a : T, b : T ) { print( "baz2", a, b ); }
func baz<T,U>( a : T, b : U ) { print( "baz3", a, b ); }
baz( a : 3 );
baz( a : 3.5 );
baz( a : 2, b : 2 );
baz( a : 2, b : 2.5 );
func swap<T>( _ a : inout T, _ b : inout T ) { let temp : T = a; a = b; b = temp; }
var ix = 4, iy = 3;
swap( &ix, &iy );
print( ix, iy );
var fx = 4.5, fy = 3.5;
swap( &fx, &fy );
print( fx, fy );
// Local Variables: //
// compile-command: "swift test.swift" //
// End: //
