A stable reference is not an immutable object
Use val when a binding should be assigned once. Use var when reassignment is part of the algorithm. Neither keyword by itself makes the referenced object's internal state immutable.
fun main() {
val topics = mutableListOf("Kotlin")
topics.add("Compose")
// topics = mutableListOf("AI") // Reassignment is forbidden.
var selected = "Kotlin"
selected = "Compose"
println(topics)
println(selected)
}
The list changes even though topics is a val. A List<T> exposes a read-only interface, but another owner may still mutate its backing collection. When you need a snapshot of a mutable collection, use toList(); this copies the collection structure, not every object inside it.
Prefer returning new values from transformations instead of sharing a mutable list across unrelated features. This makes ownership easier to understand and reduces accidental changes, especially when UI state is passed between layers.
Exercise
Create a mutable source list and two variables: a List<String> reference to that source and a snapshot created with toList(). Add an element to the source and print both.
Check: the read-only reference sees the addition; the snapshot does not. Explain why neither approach deep-copies a mutable element.