Sure. I wrote the sample, so let me attempt to explain.
background {
saveToDb(count)
}
The background function takes a lambda argument. Lambdas can "capture" state and affect it. By that I mean, forgetting "freezing", you would normally expect that changing the value of count would change the source value. So, if we forget "freezing", the if count starts at 0, the following would result in count being 1:
background {
count++
}
In order to make that happen, the lambda needs to have a reference to count, and to have a reference to count means you'll have a reverence to the class that holds it. More formally, the code should look like the following:
background {
this.count++
}
We don't need to state this.count, but only because the this is assumed.
Lambdas need to access the state they reference, and none of this is magic. Lambdas have state, which is the objects they capture. Freezing state means all state that the freezee touches. In the case of lambda functions, that means anything the code references.
In this case:
private fun saveToDb(arg:Int) = background {
println("Doing db stuff with $arg, in main $isMainThread")
}
arg:Int is a parameter. arg is frozen, but nothing in the lambda captures the parent class. If you wrote this.arg it would be an error. arg is local. Freezing it does not cascade up to the parent class.
I started writing an Intellij/AS plugin that would help warn you about these possible situations, as this is the kind of thing most likely to trip people up, but the Kotlin team told me they'd decided this memory model was going away. So, that plugin effort stopped. At some point next year this won't be an issue.
However, learning this memory model is useful. Devs tend to casually do things that are dangerous from a threading perspective. The Kotlin/Native restrictive threading model forces you to rethink how you architect your code. It's not necessarily a bad thing.
But I digress. The model is changing. In the meantime, be careful with your captured state.