Feature request: Support method overloads on parameter names like Swift

This should be allowed in Kotlin Multiplatform:

@JvmName("myFunWithFoo")
@JsName("myFunWithFoo")
fun myFun(foo: String) {}

@JvmName("myFunWithBar")
@JsName("myFunWithBar")
fun myFun(bar: String) {}

Instead we get a Conflicting overloads error. Weird thing is there is already some level of method overloads on parameter names in Kotlin/Native as seen in this generated c interop stub:

@ExternalObjCClass
open class FIROAuthProviderMeta : NSObjectMeta, FIRFederatedAuthProviderProtocolMeta {
    
    @ObjCMethod("credentialWithProviderID:IDToken:accessToken:", "@40@0:8@16@24@32")
    external open fun credentialWithProviderID(providerID: String, IDToken: String, accessToken: String?): FIROAuthCredential
    
    @ObjCMethod("credentialWithProviderID:IDToken:rawNonce:", "@40@0:8@16@24@32")
    external open fun credentialWithProviderID(providerID: String, IDToken: String, rawNonce: String?): FIROAuthCredential    
}

Those two functions should conflict but instead we are able to differentiate calls to them by specifying parameters names.

I don’t have much experience with Kotlin/Native–how would a client call those functions? If the caller didn’t specify a param name, what happens (error or is one of the methods resolved)?

1 Like

Yes the error you get is None of the following functions can be called with the arguments supplied.

Interesting.

Might be worth pointing out that method names are already part of a method’s signature (due to named params). Changes to them must already be considered an API breaking change.

It’s interesting how this works in Kotlin mapping to native functions while calling Java it does not (due to Java not always preserving method names).

I didn’t understand these parts, could you be more specific?

1 Like

Sure.

A method signature can be made up of several things. For example; return type, method name, number of params, type of params, names of params, param order, etc. If any part of the signature changes, that change is an API breaking change.

In Java, the names of parameters aren’t part of the method signature. You can change them whenever you want and not worry about the callers having to change their code.

In Kotlin, param names are part of the signature. This is required to enable calling a function with named params (e.x. myFunction(param1 = "foo", param2 = "bar")). If you change a param name, you risk breaking the callers of that method. When calling Java from Kotlin, you can’t use named params.
(If you want to see how another language handles this, Dart’s named params are explicitly declared so in the method to include the name as part of the signature, which is different from how Dart’s positional params are declared)

The reason I brought it up is that changing what’s included in a method signature is a big change–introducing a new way to break an API should not be done lightly. Since Kotlin already* considers all names of parameters as part of the method signature, requesting method resolution based on the names is a less weighty request (and should be easier to do for Kotlin).

There are still some cons. The request is to essentially no longer consider a method in conflict with another if their param names differ. There’s still plenty to discuss on interop. Calling those methods from Java would be difficult.

Even though we just talked about how Kotlin does consider param names part of a method signature by use of named params, Kotlin also does not consider method names part of the method signature when dealing with conflicts. I suspect the only reason is interop. It’s intesting that when interoping with native, we can use the @ObjCMethod to distinguish the method as unique on one platform but not in cases where that method could be used on another platform (like JVM or common kotlin).

I think the goal is to balance being able to use named params in Kotlin while still supporting easy interop with Java–and like you show in your Kotlin/Native example, still provide allowances for other languages that allow parameter name resolution.

1 Like