I'm dealing with function overloading when the par...
# getting-started
d
I'm dealing with function overloading when the parameters are lambdas and stumbled upon the following case:
Copy code
fun foo(block: String.(String) -> Unit) {

}

fun foo(block: () -> Unit) {

}

fun main() {
    foo { it: String ->
        // calls foo(block: String.(String) -> Unit)
    }
    
    foo { // ERROR
        // how to call foo(block: () -> Unit)
    }
}
Basically is there a way to specify in the second case that I want to call
foo(block: () -> Unit)
. When I specified the type of the lambda argument, it seemed that the compiler was able to figure it out, however
it: Unit
doesn't work for the second case.
s
I don’t think I’ve ever actually read documentation that discusses this particular syntactic construction, but try calling the second function like this:
Copy code
foo { ->
  // do stuff here
}
1
this explicitly declares that this lambda takes no parameters, disambiguating the function call
d
okay, that worked. Thanks!
👍 2
y
I've literally never seen that syntax before wow. This really should be documented
👍 4
Apparently this is part of the official grammar:
lambdaLiteral (used by annotatedLambdafunctionLiteral)
  : '{' statements '}'
  | '{' lambdaParameters? '->' statements '}'
  ;
that question mark means 0 or 1 of the item, and lambdaParameters defines the whole list of parameters, and so according to the grammar you can have no parameters but still use the
->
before your statements. So I guess it is documented and expected behaviour, it's just that no one actually mentions it anywhere outside of the grammar!
1
😮 1
d
I admit it, it didn't even occur to me to look for the grammar. Thanks!
a
It's kind of neat that you can do this, but wouldn't it be clearer for a reader of the code if these functions had different names instead? If the caller is trying to make a conscious choice of which one is being invoked, are their purposes not different?
☝️ 1