The following statement compiles and prints "fun: called"
:
fun main(vararg args: String) {
fun toCall(arg: String) = println("fun: $arg")
val toCall = fun(arg: String) = println("val: $arg")
toCall("called")
}
Note: the same problem would arise if they were top level declarations or inside a class, this is just the simplest repro with local function/variable.
Looking for clarification on why this compiles in the first place?
What rule comes into play that picks the function over the property?
Note: it's possible to call the val
one through:
(toCall)("called")
toCall.invoke("called")
This document regarding name resolution contains details about it.
I will just quote some passages out of it specifically dealing with your problem. It contains several other interesting things as well, but I think I would end up copying everything here then ;-) If you are interested, I can only recommend you to read it completely.
Summarizing, the compiler divides the functions (member/extension/member extension)/properties into groups and decides which one to call first... The properties are put in the group of the invoke
-functions and in the following passage you already see why the function was taken before your val
:
The property is considered together with the
invoke
function. Groups of properties withinvoke
functions are mixed with groups of regular functions, in a sense that a group of properties can have higher priority than a group of functions and vice versa. However, functions and properties can’t go in one group: the function always surpasses the property of the same category. Both the property and theinvoke
function determine the priority of the group: we compare the priority of the property and of theinvoke
function and the "lowest" one becomes the group priority.
That's why the function was considered first here and the property later. As soon as you specified invoke
it was clear that it can only be the property as the function itself has no visible invoke
(lets not go down the byte code now ;-)). Now (toCall)
behaves similarly. Here it is clear, that toCall
can only be the property. It isn't possible to call (toCall)
with the function (compile errors: function invocation expected / the function invoke
is not found).
The linked document also contains a sample with a member property function followed by this statement, which basically also confirms the previous regarding local functions:
Note that there is no member function named foo, but if it was present, it would be put into a separate group with the highest priority.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With