Hi,
I have a proposal regarding implicit names of lambda parameters. Currently the documentation states
One other helpful convention is that if a function literal has only one parameter, its declaration may be omitted (along with the ->), and its name will be it
Here are the disadvantages of it
implicit name I see:
-
Its usage can be sometimes confusing. Consider the following contrived example
data class SomeModel(val data: List<Int>) listOf(SomeModel(data = listOf(1,2,3)), SomeModel(data = listOf(5,6,7,8))) .forEach { // forEach `it` print(it) it.data.reduce { // It may seem that the following `it` represetns the first reduce arg // But it's still the same `it` from forEach! a, b -> a + b + it.data.first() } }
-
It’s too restrictive. Why there is implicit name only for a single parameter?
I think, Kotlin could overcome these disadvantages by implementing Shorthand Argument Names the same way as in Swift programming language.
Here are the specs.
Quick Overview:
-
Instead of
it
name it’s better to use numeric shorthand argument names which refer to the values of the lambda’s arguments like this:$0, $1, $2
, and so on. -
To prevent ambiguity the usage of these names should be restricted to the enclosing lambda. For example,
$0
in nested scope must not refer to the argument from the outer scope. -
With shorthand argument names the previous example can be rewritten as
data class SomeModel(val data: List<Int>) listOf(SomeModel(data = listOf(1,2,3)), SomeModel(data = listOf(5,6,7,8))) .forEach { $0.data.reduce { // Now there is no ambiguity // $0 refers to the argument value of the first reduce parameter // $0 cannot refer to the first argument of forEach // Note: if reduce hadn't parameters at all the usage of $0 should give a compile time error $0 + $1 } }
Hope this all makes sense.