Issue
consider a SAM defined in Java
public interface Transform {
public String apply(String str);
}
This interface supports lambda to type conversion in Kotlin automatically
fun run(transform: Transform) {
println(transform.apply("world"))
}
run { x -> "Hello $x!!" } // runs fine without any issues
But now consider a Kotlin interface
interface Transform2 {
fun apply(str: String): String
}
Now the only way to invoke the run function would be by creating an anonymous instance of Transform2
run(object : Transform2 {
override fun transform(str: String): String = "hello $str!!"
})
but if we make the Transform2 interface a functional interface then the below is possible
run { str -> "hello $str!!" }
Why the Kotlin compiler cannot automatically type cast lambdas to matching interfaces (just as it does with Java interfaces) without needing to explicitly mark the said interfaces as a functional interface.
Solution
I've found some kind of a rationale in a comment in KT-7770:
... treating all the applicable interfaces as SAM might be too unexpected/implicit: one having a SAM-applicable interface may not assume that it will be used for SAM-conversions. Thus, adding another method to the interface becomes more painful since it might require changing syntax on the call sites (e.g. transforming callable reference to object literal).
Because of it, current vision is adding some kind of modifier for interfaces that when being applied:
- Adds a check that the interface is a valid SAM
- Allows SAM-conversions on call sites for it
Something like this:
fun interface MyRunnable { fun run() }
Basically, he is saying that if the SAM conversion were done implicitly by default, and I add some new methods to the interface, the SAM conversions would no longer be performed, and every place that used the conversion needs to be changed. The word "fun" is there to tell the compiler to check that the interface indeed has only one abstract method, and also to tell the call site that this is indeed a SAM interface, and they can expect the author to not suddenly add new abstract methods to the interface, suddenly breaking their code.
The thread goes on to discuss why can't the same argument can't be applied to Java, and the reason essentially boils down to "Java is not Kotlin".
Answered By - Sweeper
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.