Hey all! Is there an advantage to passing a lambda...
# compose
f
Hey all! Is there an advantage to passing a lambda vs wrapping it? E.g.
Copy code
@Composable
fun MyButton(onClick: () -> Unit) {
    Button(onClick = onClick) { ... }
}
// vs
@Composable
fun MyButton(onClick: () -> Unit) {
    Button(onClick = { onClick() } { ... }
}
(this is probably a more general kotlin question, but I see both patterns in compose code and it's unclear if one is better / worse than the other)
z
Wrapping it means allocating another lambda object, although R8 maybe can optimize that out, idk. It's really more of a style issue than anything though I think.
👍 2
a
avoid wrapping where you can, a lot of compose code wraps when the lambda types don't match, e.g. when there's a parameter or receiver type involved that differs
z
It would be nice if kotlin could automatically wrap when a function (or reference) that doesn’t have a receiver is passed where one with a receiver is expected
2
a
it'd have an element of convenience but unless it also didn't imply a hidden wrapper allocation I'm kind of glad it doesn't
z
it can do it with passing non-suspend functions where suspend functions are expected, idk how that actually works but it also involves an extra parameter that doesn’t need to be passed. In the Show Kotlin Bytecode it looks like the only different is it literally just casts a
Function0
to a
Function1
anyway, sorry for hijacking the thread
c
I always feel like I'm guessing and checking. Sometimes: •
blah
works • `blah()`works •
{blah()}
works /shruggie. need to get more comfortable with lambdas/functions in kotlin 😄
a
Should I wrap { blah(someParam) } inside remember?
z
I think the thing that made lambdas click for me was doing some functional programming training. There used to be a good course on Coursera from the guy who invented Scala, really turned a lot of lightbulbs on for me.
👍 1
@Abhinav Suthar it depends 😉 need more context to answer
a
Assume this composable
Copy code
@Composable
fun Parent(paramA: String, onChildBClick: (String) -> Unit){
    ChildA(paramA)
    ChildB( onClick = { onChildBClick("string") })
}
Now assume on re-composition, paramA changes so Parant function will re-compose. So ChildA will get re-composed because paramA has been updated. And if I understand it correctly, ChildB will also recompose because onClick lambda function has been updated (new lambda created). I want to prevent this extra recomposition of ChildB by wrapping the lambda inside remember block or should I not be worried about it if it makes no big difference?
@Zach Klippenstein (he/him) [MOD] you also said it depends. It depends on what exactly?
z
I wouldn’t worry about it. This sort of pattern is extremely common and any attempt to outsmart the default behavior will make the code much more complicated and harder to read for very little benefit
1
🙏 1
a
agreed; if the IDE autosuggest says you can simplify it to just pass the same function object as a parameter "unnecessary lambda creation" then take the suggestion, otherwise don't worry
if all of the captured values of a lambda created during composition are stable and unchanged then compose does some caching around it anyway
🙏 1