In this snippet, we've defined the read-only greetingProvider variable to store a function that takes no arguments and returns String:
val greetingProvider: () -> String = { "Hello" }
Because this is a read-only variable, it must be initialized with a value. In this case, we use the lambda syntax to assign a function that returns the string literal "Hello". We can then use the variable to invoke the function.
Now, consider the following code snippet in which the function assigned to greetingProvider is run twice, but using different syntax for each invocation:
fun main(args: Array<String>) {
var greeting = greetingProvider() // invoke with parentheses
greeting = greetingProvider.invoke() // use the invoke method
}
The first invocation is done by adding parentheses to the variable and calling it as if it were any other function. The second line takes advantage of the invoke() function that is generated by the compiler when defining a function variable.