Search code examples
functionkotlinlambdasyntax

What is the benefit in removing parentheses when using Kotlin lambda expressions?


Consider this example given here: https://stackoverflow.com/a/53376287/11819720

fun onClick(action: () -> Unit) { ... } 

view.onClick({ toast(it.toString())} )
view.onClick() {toast(it.toString()) }
view.onClick { toast(it.toString()) }

and this code:

fun convert(x: Double, converter: (Double) -> Double): Double{
    val result = converter(x)
    println("$x is converted to $result")
    return result
}
fun convertFive (converter: (Int) -> double): Double{
    val result = converter(5)
    println(" 5 is converted to $result")
    return result
}
fun main (args: Array<String>){
    convert(20.0) { it * 1.8 + 32 }
    convertFive { it * 1.8 + 32 }
}

It seems the effort is to save on writing a few parentheses at the risk of confusing a reader. Would it not be better if it was kept standard? The usual way to use the functions in the second example would be:

convert(20, {it * 1.8 + 32})
convertFive({it * 1.8 = 32})

but IntelliJ will complain and suggest moving the lambda out of the parenthesis. Why? Is there a practical benefit? Seems like writing 10 + 2 * 5 / 34 instead of 10 + (2 * 5) / 34.


Solution

  • The real benefit of the trailing-braces lambda is that, like all the best language features, it changes the way you think.

    The examples you have provided are just as well written with parentheses, and I agree that the IntelliJ suggestion to use the trailing form all the time is unnecessary...

    But when I write something like this:

    with(someObject) {
        doSomething();
        doSomethingElse();
    }
    

    It looks like I'm using a cool new feature of the language even though I'm really just calling a function.

    The result is that people start thinking like they can write functions that add things to the language, because they kinda can, and that leads them to create new ways of doing things for the people who use their code.

    The type-safe builder pattern is a great example of this. A lot of the Kotlin language features work together so that, even though it's just calling functions and passing lambdas, it provides a new experience for the developers that use it.

    They get a whole new way to instantiate complex objects that is much more natural than the old ways, and nothing needed to be added to the language just for that -- all the little building-block features can be used for many other things.