Stylianos Gakis
01/18/2023, 4:47 PM@Composable fun foo() {
@Composable fun example1() {}
val example2: @Composable () -> Unit = {}
if(..) {example1()} else {example2(); example2()}
}
If it’s a val
, will it have to do any extra work on each recomposition as if I was doing val x = someComputation
in composition? Maybe anything that the compiler plugin does better in one way? In general I guess my question is, is there any special reason why I would want to go with one over the other? Or if I really should just make it a private top level composable instead?Zach Klippenstein (he/him) [MOD]
01/18/2023, 4:56 PMLandry Norris
01/18/2023, 5:40 PMZach Klippenstein (he/him) [MOD]
01/18/2023, 6:10 PMStylianos Gakis
01/18/2023, 6:23 PMComposableTest.kt
with no package:
@Composable fun example1() {}
is
GETSTATIC ComposableTestKt$asd$1.INSTANCE : LComposableTestKt$asd$1;
---
val example2: @Composable () -> Unit = {}
is two lines
GETSTATIC ComposableTestKt$asd$example2$1.INSTANCE : LComposableTestKt$asd$example2$1;
CHECKCAST kotlin/jvm/functions/Function0
then calling them
example1()
is
INVOKEVIRTUAL ComposableTestKt$asd$1.invoke ()V
---
example2()
is
INVOKEINTERFACE kotlin/jvm/functions/Function0.invoke ()Ljava/lang/Object; (itf)
And for a normal top level private function with signature:
@Composable private fun example3() {}
Calling it is:
INVOKESTATIC ComposableTestKt.example3 ()V
So there are some differences, not to say I can really interpret what those are, this is the first time I ever really look at bytecode tbh 😄
One is using INVOKEVIRTUAL
, one INVOKEINTERFACE
the other INVOKESTATIC
, not sure if this does after all have any implications on how the compiler interprets stable-ness and so on.
Might be interesting to try and run the compose compiler reports on these, might do that sometime to see if that tells me anything.ephemient
01/18/2023, 6:39 PM()V
indicates that the compose compiler isn't actually operating, which is a known issue with using "Show bytecode" https://youtrack.jetbrains.com/issue/KTIJ-23396Zach Klippenstein (he/him) [MOD]
01/18/2023, 7:46 PMStylianos Gakis
01/23/2023, 1:56 PMval dismissButton = @Composable {
TextButton(onClick = { dismiss() }) {
Text(stringResource(android.R.string.cancel))
}
}
syntax, I got a crash with stacktrace
java.lang.IllegalStateException: Compose Runtime internal error. Unexpected or incorrect use of the Compose internal runtime API (Unexpected anchor value, expected a negative anchor). Please report to Google or use <https://goo.gle/compose-feedback>
In fact very similar to this issue https://issuetracker.google.com/issues/204897513
Making a sample project I could not for the life of me reproduce it. In my project there’s some shenanigans going on with showing an androidx.compose.material3.AlertDialog
and the text is defined higher up and passed in there in various places depending on a boolean conditional.
Anyway, switched to the local @Composable fun
syntax and it no longer crashes now. Can’t really report this without having a repro though. Should I report with the stacktrace besides the fact that I can’t actually reproduce it and I can’t share the code where this bug does in fact happen?