Can this kind of interface marked as @Immutable? `...
# compose
b
Can this kind of interface marked as @Immutable?
Copy code
interface ColorSpec {
    @Composable
    operator fun invoke(): Color

    companion object {
        fun fromColor(lightVariant: Color, darkVariant: Color): ColorSpec = object : ColorSpec {
            @Composable
            override fun invoke(): Color = if (Theme.isDarkTheme) darkVariant else lightVariant
        }
    }
}
b
I checked that already, also https://medium.com/androiddevelopers/jetpack-compose-stability-explained-79c10db270c8. Properties of ColorSpec don't change, but @Composable invoke() can produce different results (depending on Theme.isDarkTheme, which is backed by value in CompositionLocalProvider).
a
@Stable
is probably more semantically correct but the way you've set things up here it won't help you much since you're not defining
equals
for the objects returned from your utility. Different but equivalent objects can't skip recomposition if you don't implement equals
b
So if I make fromColor return a
data class
that implements ColorSpec, then I still should use
@Stable
?
a
That'd be one way to do it
b
I don't get why use @Stable instead of @Immutable then..
a
If you have an interface that can be implemented by others then stable keeps the contract less strict but compose will give you the same skipping behavior either way
b
Gotcha. Does adding @immutable to extending
data
classes will improve skipping behavior?
a
I'd assume it inherits the interface's stability since otherwise it wouldn't meet the is-a contract, but I'd need to check. Most data classes will get the compiler plugin to infer the class as stable anyway though
At least data classes like the one you listed here where the only properties are
Color
or something else that's known stable
To be clear, compose treats
@Immutable
and
@Stable
in exactly the same way for skipping behavior
b
^ didn't know that, I thought it would be different
a
Not currently, anyway