Function overload resolution rules


(Toni Suter) #1

Hi,

I am trying to get a better understanding of Swift's function overload resolution rules.
As far as I can tell, if there are multiple candidates for a function call, Swift favors
functions for which the least amount of parameters have been ignored / defaulted. For example:

// Example 1
func f(x: Int) { print("f1") }
func f(x: Int, y: Int = 0) { print("f2") }
f(x: 0) // f1

// Example 2
func f(x: Int, y: Int = 0) { print("f1") }
func f(x: Int, y: Int = 0, z: Int = 0) { print("f2") }
f(x: 0) // f1

It also looks like Swift favors functions with default-value parameters over functions with variadic parameters:

func f(x: Int = 0) { print("f1") }
func f(x: Int...) { print("f2") }

f() // f1
f(x: 1) // f1
f(x: 1, 2) // f2 (makes sense because f1 would not work here)
f(x: 1, 2, 3) // f2 (makes sense because f1 would not work here)

But then I tested functions with default-value parameters and variadic parameters and things start to get weird.
For example, this must be a bug, right?

func f(x: Int..., y: Int = 0) { print(x, y) }
func f(x: Int...) { print(x) }

f() // []
f(x: 1) // [1]
f(x: 1, 2) // [1, 2] 0
f(x: 1, 2, 3) // [1, 2, 3]

I think, in this example, it should always call the second overload, because
no parameter is ignored / defaulted. What do you think?

Thanks and best regards,
Toni


(Mark Lacey) #2

Hi,

I am trying to get a better understanding of Swift's function overload resolution rules.
As far as I can tell, if there are multiple candidates for a function call, Swift favors
functions for which the least amount of parameters have been ignored / defaulted. For example:

// Example 1
func f(x: Int) { print("f1") }
func f(x: Int, y: Int = 0) { print("f2") }
f(x: 0) // f1

// Example 2
func f(x: Int, y: Int = 0) { print("f1") }
func f(x: Int, y: Int = 0, z: Int = 0) { print("f2") }
f(x: 0) // f1

It also looks like Swift favors functions with default-value parameters over functions with variadic parameters:

func f(x: Int = 0) { print("f1") }
func f(x: Int...) { print("f2") }

f() // f1
f(x: 1) // f1
f(x: 1, 2) // f2 (makes sense because f1 would not work here)
f(x: 1, 2, 3) // f2 (makes sense because f1 would not work here)

But then I tested functions with default-value parameters and variadic parameters and things start to get weird.
For example, this must be a bug, right?

func f(x: Int..., y: Int = 0) { print(x, y) }
func f(x: Int...) { print(x) }

f() // []
f(x: 1) // [1]
f(x: 1, 2) // [1, 2] 0
f(x: 1, 2, 3) // [1, 2, 3]

I think, in this example, it should always call the second overload, because
no parameter is ignored / defaulted. What do you think?

Can you open a new bug report for this at bugs.swift.org <http://bugs.swift.org/>?

Mark

···

On Sep 30, 2016, at 5:02 AM, Toni Suter via swift-users <swift-users@swift.org> wrote:

Thanks and best regards,
Toni
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Vladimir) #3

Hi,

I am trying to get a better understanding of Swift's function overload
resolution rules.
As far as I can tell, if there are multiple candidates for a function call,
Swift favors
functions for which the least amount of parameters have been ignored /
defaulted. For example:

I do believe this *should* be a bug in Swift's parser. It is not obvious the intention of the user, i.e. which function *user* want to call.
IMO there should be no hidden or complex rules on how Swift selects the candidate for function calls if parameters suits for a number of implementations.
IMO The only rule should be - if it is not clear from the parameter list which func should be called - compilation error must be thrown. This will be "Swifty" which is "Safe by default". Current situation is not safe by default.

···

On 30.09.2016 15:02, Toni Suter via swift-users wrote:

// Example 1
func f(x: Int) { print("f1") }
func f(x: Int, y: Int = 0) { print("f2") }
f(x: 0) // f1

// Example 2
func f(x: Int, y: Int = 0) { print("f1") }
func f(x: Int, y: Int = 0, z: Int = 0) { print("f2") }
f(x: 0) // f1

It also looks like Swift favors functions with default-value parameters
over functions with variadic parameters:

func f(x: Int = 0) { print("f1") }
func f(x: Int...) { print("f2") }

f() // f1
f(x: 1) // f1
f(x: 1, 2) // f2 (makes sense because f1 would not work here)
f(x: 1, 2, 3) // f2 (makes sense because f1 would not work here)

But then I tested functions with default-value parameters and variadic
parameters and things start to get weird.
For example, this must be a bug, right?

func f(x: Int..., y: Int = 0) { print(x, y) }
func f(x: Int...) { print(x) }

f()// []
f(x: 1)// [1]
f(x: 1, 2)// [1, 2] 0
f(x: 1, 2, 3)// [1, 2, 3]

I think, in this example, it should always call the second overload, because
no parameter is ignored / defaulted. What do you think?

Thanks and best regards,
Toni

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Toni Suter) #4

I created a bug report here: https://bugs.swift.org/browse/SR-2810

Best regards,
Toni

···

Am 30.09.2016 um 19:47 schrieb Mark Lacey <mark_lacey@apple.com>:

On Sep 30, 2016, at 5:02 AM, Toni Suter via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Hi,

I am trying to get a better understanding of Swift's function overload resolution rules.
As far as I can tell, if there are multiple candidates for a function call, Swift favors
functions for which the least amount of parameters have been ignored / defaulted. For example:

// Example 1
func f(x: Int) { print("f1") }
func f(x: Int, y: Int = 0) { print("f2") }
f(x: 0) // f1

// Example 2
func f(x: Int, y: Int = 0) { print("f1") }
func f(x: Int, y: Int = 0, z: Int = 0) { print("f2") }
f(x: 0) // f1

It also looks like Swift favors functions with default-value parameters over functions with variadic parameters:

func f(x: Int = 0) { print("f1") }
func f(x: Int...) { print("f2") }

f() // f1
f(x: 1) // f1
f(x: 1, 2) // f2 (makes sense because f1 would not work here)
f(x: 1, 2, 3) // f2 (makes sense because f1 would not work here)

But then I tested functions with default-value parameters and variadic parameters and things start to get weird.
For example, this must be a bug, right?

func f(x: Int..., y: Int = 0) { print(x, y) }
func f(x: Int...) { print(x) }

f() // []
f(x: 1) // [1]
f(x: 1, 2) // [1, 2] 0
f(x: 1, 2, 3) // [1, 2, 3]

I think, in this example, it should always call the second overload, because
no parameter is ignored / defaulted. What do you think?

Can you open a new bug report for this at bugs.swift.org <http://bugs.swift.org/>?

Mark

Thanks and best regards,
Toni
_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users