<@UJBKXD0HH> I’m excited that `onPreCommit` and `o...
# compose
z
@Adam Powell I’m excited that
onPreCommit
and
onCommit
are being merged! They were pretty confusing.
a
🙂 we're still discussing impact and messaging of this one, I appreciate the vote of support
this isn't likely to be the only upcoming change to the lifecycle effect functions, we've been having a lot of discussions around use cases, patterns, and antipatterns and how we want to shape the APIs going forward
this one is more mechanical so that we can get rid of some uncontrolled handler/choreographer posting behavior that onCommit does
a lot of that discussion has been around producer/consumer patterns, formalizing those, and trying to discourage uses of the following (anti)pattern:
Copy code
var state by remember { mutableStateOf<Thing>(value) }
onCommit(state) {
  applySideEffect(state)
}

// elsewhere...
Modifier.event {
  state = deriveFrom(it)
}
👍 3
which comes about when someone essentially wants a
Flow
or similar from some
State
that they already have but the alternative way to create that bridge is a lot more complicated
along that path we've been playing with some things that might look roughly like this in usage:
Copy code
val myFlow = flow {
  observeSnapshotUpdates {
    emit(deriveFrom(state1, state2))
  }
}
which would then let us remove/reposition some of the lifecycle effect APIs to discourage off-label usage and encourage intended patterns
z
so the lambda passed to
observeSnapshotUpdates
would record reads of snapshot/state objects, and re-invoke the lambda when they’re changed?
a
right, as a
suspend fun
that returns
Nothing
😮 1
context-preserving with the caller to permit the
emit
pattern above
block executed in an isolated snapshot itself, likely an immutable snapshot, so state writes would not be permitted in that block. We're still discussing that.
z
it wouldn’t be a
@Composable
function though, but basically a “special type” of function that would basically be have a subset of the behavior?
a
yeah this is lower level than compose and knows nothing about it, this is snapshots only
z
just trying to fit it in my mental model – is “a
@Composable
function is like a
observeSnapshotUpdates
function that also has an implicit
Composer
and can emit stuff” approaching the general idea?
a
also nothing special about codegen either, no compiler plugin required to use it
👍 1
kind of? While we're composing we install special snapshot observers for reads, so we record the recompose scopes where reads of specific values happen
when a snapshot is applied we invalidate any recompose scopes that previously read any snapshot state that changed in that commit
z
right
a
but all of that sits above the snapshot system itself; the proposed api above would be operating at the same level the compose runtime itself does
(and if we were so inclined the snapshot system could be its own separate artifact)
z
another way to think of it is that
observeSnapshotUpdates
is basically a
collect{}
of the snapshot “system”. Kind of like (pseudo-code)
combineLatest(snapshotSystem[state1], snapshotSystem[state2]).collect { (state1, state2) -> … }
a
More or less
z
obviously that’s not a perfect analogy, but if you think of the snapshot system as a reactive producer, then this is very similar to flow’s collect method
neato
really interesting how these concepts interact with coroutines so naturally
a
yeah! Compose does a really good job of working with declarative transformations of snapshots in time, and coroutines provide the over-time part. They work great together.
🙌 1
z
that “in time/over-time” bit should be in a blurb somewhere, that’s a great way to phrase it
a
if I were better with any sort of graphical editor I'd draw it as your UI snapshot as a plane moving in time along a Z-axis
z
I can’t wait for that Android Dev Summit talk in 2 or 3 years 😉
a
I remember when you out it in other words a few months ago, kinda stuck with me. I agree it's a nice way of phrasing it. https://kotlinlang.slack.com/archives/CJLTWPH7S/p1586614342218200?thread_ts=1586565247.204300&amp;cid=CJLTWPH7S
s
I'd draw it as your UI snapshot as a plane moving in time along a Z-axis
Time travelling here :)