Nested lambda calls is an issue when using Jetpack Compose
or using any Coroutines API take this as an example:
@Composable
fun SomeComponent() {
LaunchEffect(Unit) {
launch {
withContext(Dispatchers.IO) {
loadFromCache()
}
}
}
Card {
someList.forEach {
Column {
// this is already deep and we didn't yet written any content
}
}
}
}
My proposed solution is a syntax sugar for the last lambda argument to have another special
syntax for providing it just like somefun(...) { /*body*/ }
. The syntax could be anything but it
is a MUST if the Kotlin
team is heading more and more towards making Kotlin
a content
language (e.g. kotlin-html
, kotlin-css
, Jetpack Compose
, etc.)
My syntax proposal is somefun(...): /* stmt */
where stmt
is a single statement just like
in if (...) /* stmt */
and for (...) /* stmt */
. This enables a lot of concise code to be written.
Take for example:
for (it in 0..100) if (it % 2 == 0)
println(it)
// Woudl be replacable with
0..100.forEach: if (it % 2 == 0)
println(it)
for (n in 0..100) if (n % 2 == 0)
println(n)
// Woudl be replacable with
0..100.forEach: n -> if (n % 2 == 0)
println(n)
listOf(0..100).flatten().asFlow().collect {
if (it % 2 == 0) launch {
println(it)
}
}
// Woudl be replacable with
listOf(0..100).flatten().asFlow().collect:
if (it % 2 == 0) launch:
println(it)
LaunchEffect(Unit) {
launch {
withContext(Dispatchers.IO) {
loadFromCache()
}
}
}
Card(modifier) {
someList.forEach { value ->
Column {
Content(value)
}
}
}
// Woudl be replacable with
LaunchEffect(Unit):
launch: withContext(Dispatchers.IO):
loadFromCache()
Card(modifier): someList.forEach: value -> Column:
Content(value)
One last thing, this syntax sugar could be a solution for some ugly code we are used to:
require(someCondition) { "Some message" }
// Woudl be replacable with
require(someCondition): "Some message"
// not saying this is ugly, but it might be better?
implementation(libs.google.tink)
implementation: libs.google.tink // obviously updates in gradle is required too for this to work