Philipp Mayer
09/02/2020, 8:53 AMkqr
09/02/2020, 9:01 AMthanksforallthefish
09/02/2020, 9:01 AMCasey Brooks
09/02/2020, 2:18 PMfun interface
, I don’t have to compromise on type-safety or legibility. I write the library using a normal interface for safety and clean library code, and consumers can just use SAM lambdas instead of anonymous objectsPhilipp Mayer
09/02/2020, 2:22 PMNir
09/02/2020, 3:31 PMIan Lake
09/02/2020, 3:42 PMCasey Brooks
09/02/2020, 3:47 PMkotlin
typealias MyCallback<T> = (String, Int, T) -> T
fun <T> runStuff1(t: T, block: MyCallback<T>) : T {
val s = "s1"
val i = 1
return block(s, i, t)
}
fun <T> runStuff2(t: T, block: (String, Int, T) -> T) : T {
val s = "s2"
val i = 2
return block(s, i, t)
}
As far as the code itself goes, it’s perfectly type-safe. But there’s no way to enforce the correct
usage of the MyCallback
typealias, so you might run into a situation where some methods are using
the typealias version of the parameter and some are using the lambda syntax. It’s perfectly
legitimate code, but the “type” is not safely used throughout. Further, if changes were made to the
MyCallback
interface, those places using the lambda syntax would not be updated to reflect those
changes.Nir
09/03/2020, 4:57 PMNir
09/03/2020, 4:57 PMNir
09/03/2020, 5:00 PMCasey Brooks
09/03/2020, 5:12 PM(String, Int, T) -> T
) or typealias (MyCallback<T>
) syntax, and both are valid as far as usage of the function is concerned. But the intention in setting up the typealias is that it would be used everywhere, and so writing functions with a parameter defined using the lambda syntax breaks that intention, but because it’s a typealias the code will still compile. And then if you were to use IDE refactoring tools to change the definition of the typealias, the functions using the lambda syntax will not be updated and your library code is now broken. And a similar thing happens on the consumer side if they are passing that lambda parameter around themselves.
If you used a fun interface
, you could not write function parameters with lambda syntax. They all would be the same type, and that gets passed around, called, and refactored safely everywhere. The consumer of the library is forced to use SAM lambdas (acknowledging the strong-type of the interface), and anywhere they choose to pass that lambda around is a strongly-typed object. The “safety” i’m referring to is more more about the declarations of functions and the types of its parameters than the actual call-site.Nir
09/03/2020, 5:26 PMNir
09/03/2020, 5:26 PMNir
09/03/2020, 5:27 PMMyCallback
is an fun interfaceCasey Brooks
09/03/2020, 5:42 PMMyCallback
as a fun interface
, it can no longer be assigned to (String, Int, T) -> T
, and it can’t be passed into other methods with (String, Int, T) -> T
as a parameter. If it was a typealias, you can freely use change between one and the other. Maybe this example will help (nevermind the infinite recursion, just notice how it fails to compile. Also, try removing fun
from the interface and see how things change) https://pl.kotl.in/fulUE6NgrNir
09/03/2020, 6:22 PMNir
09/03/2020, 6:22 PMNir
09/03/2020, 6:22 PMNir
09/03/2020, 6:23 PM