Hi! Found out that some google code (pic) has regu...
# compose
d
Hi! Found out that some google code (pic) has regular (non-composable) functions with
@Stable
annotation. Is there any sense in it? Isn't this annotation only applicable for composable functions?
a
When applied to function, this annotation tells compose compiler that for the same input parameters this function will have equal return
d
But isn't composable called in a whole? Compose compiler can skip even non-composable functions?
a
Oh, no. Non-composable function will not be skipped. Some other compiler optimizations related to equality checks applied here i believe
It helps in the following example:
Copy code
@Composable
fun App() {

    Something(foo(1))
    Something(bar(2))
}

class IntWrapper(
    val value : Int
)

@Composable
fun Something(intWrapper: IntWrapper) {
    println(intWrapper.value)
}

@Stable
fun foo(x : Int) = IntWrapper(x)

fun bar(x : Int) = IntWrapper(x)
Something
will be skipped during recomposition if its parameter is a result of a stable function
d
Is there sense to annotate function when return type is already marked as Stable(or stable by any other reason)?
a
Stable class doesn't require the
equals
result of 2 "equal" instances to always be
true
. It must always be "the same" (as i understand from the docs). When the 1st rule is fulfilled, function annotation is probably redundant. It is my guess, it can be wrong
So there is a sense, when
equals
is not implemented or class is not immutable
d
Thanks
a
CMIIW, but recomposition totally depends on param stability and it has nothing to do with the method who is calculating the values
Didn't get it what difference it would make if we remove @stable annotation if we are talking about
Something
being skipped then it will always skip until
intWrapper
changes
Tried a example
Copy code
@Composable
private fun Demo() {
    Column {
        var state by remember { mutableStateOf(3) }
        Block(result = foo(2))
        Text(text = "hey $state")
        Button(onClick = { state++ }) {
            Text(text = "recompose")
        }
    }
}

@Composable
private fun Block(result: Result) {
    println("foo recomposing Block")
    Text(text = "result inside ${result.x}")
}

@Stable
fun foo(x: Int): Result {
    println("foo calculating foo")
    return Result(x)
}

data class Result(var x: Int)
if we go as per what discussed above since
foo
method calculating
Result
is Stable so
Block
should skip but it will not bcz
Result
is unstable but if I remove Stable from foo and make Result Stable it will skip