Function Literals


#1

I'm wondering about this:

 
val funLit = { String.() ->
    println("funLit()")
}

I'm not really sure what the syntax means in this case. What is the type of funLit and why can I call it the same way as an extension function? What is the advantage declaring it like that (instead of a extension function)?


#2

The type of funLit is ExtensionFunction<String, Unit>.

With  the { } syntax you create either a callable Function ( () -> Unit)  or an Extensionfunction ( Type.() -> Unit), which can be used for  lazy evaluation.
Declaring an Extensionfunction like “public fun String.funLit() { … }” is the same as your funLit.


#3

Thanks! I missed that the type changes from Function... to ExtensionFunction....

So basically Kotlin will allow a function to be used as an extension function if the type is ExtensionFunction? Of course I had to try that out in all possible ways. I didn’t succeed creating an extension function in Java, though. There, I have the correct types and interfaces available but I don’t seem to be able to access the result from Kotlin. Is there a way to do that?

But more importantly, I’m wondering about the use cases for declaring extension functions as lambdas. You mention lazy evaluation but I don’t see how that can be the case (as extension functions do not have state of their own). I also can’t imagine that you would want to pass extension functions as a parameter to something else.

Looking at the byte code, you would at least be able to pass such an extension function literal around (because they compile to an instance of ExtensionFunction) whereas “real” extension functions compile to static methods.


#4

It's useful when creating DSLs, for example: Type-safe Groovy-style builders.


#5

I meant that lambdas in general can be used for lazy evaluation (e.g. infinite PrimeNumber iterator).

One usage of the local ExtensionFunction I can think of is when a method requires an ExtensionFunction and your ExtensionFunction is only used at one place.,
so there is no need to declare it explicitly.


#6

Thanks. So basically it's about two things: Given that you can call function literals without brackets and the fact that the extension function provides access to the receiver that syntax is mainly relevant to build a DSLs.


#7

It's like they read your post a couple of weeks before :)

Extensionfunctions like { Type.() -> … } are deprecated with the new M11.
You should to write “val funLite = fun String.() -> { println(“funLite”) }” from now on.

So { … } are Functions only now.