Why are function types stable in Compose? At first, this seems like a strange decision. Lambda expressions can capture mutable or unstable values. Why is () → List stable, if List is unstable? Does it make sense? Yes!
Abusing function type stability is actually pretty hard, especially in composable functions, where all functions are memoized by default. That means, each lambda is remembered with all captured variables used as keys. If lambda captures x, new lambda is created whenever x changes. That means lambda identity depends on identity of whatever it captures, so also on those variables stability.
But what about lambdas from view models? Those are typically either view model functions, which only change if view model changes. In some cases, lambdas are created in view models and passed to UI, but such lambdas only trigger recomposition if you create a new one, which is a behavior that we should be aware of, as it can be abused. If, for instance, they read and return value from StateFlow, this value change would not trigger recomposition, but such a use would be against the best practices.
It is also worth mentioning, that in modern days Strong Skipping Mode is used in most projects, and the key difference between stable and unstable type is how they are compared: stable with == and unstable with ===. Lambdas quality compare identity anyways (so == and === give the same result), so their stability makes little difference.
