min
05/20/2026, 11:17 AMChange need both an Applier and a SlotWriter? The explanation below makes it sound like it’d only need an Applier, since each is to be applied by it once all @Composable functions have run. Shouldn’t the Applier then take care of flushing changes to the slot table via a SlotWriter or whatever?jw
05/20/2026, 11:33 AMjw
05/20/2026, 11:34 AMjw
05/20/2026, 11:36 AMshikasd
05/20/2026, 11:37 AMApplier is only for node operations, SlotWriter is for writing composition things. You can think about it as SlotWriter making internal edits and Applier is making user facing (node related) edits.min
05/20/2026, 12:03 PMComposer composes @Composable functions.
2. The Composer updates the corresponding Composition based on what it recorded.
3. The Composition materialises a tree (eg a LayoutNode tree) from itself.
But rather:
1. A Composer composes @Composable functions.
2. The Composer submits updates to…
◦ The corresponding Composition to be executed by a SlotWriter.
◦ The tree materialised from the Composition to be executed by an Applier.
And the submitted updates are either scheduled or executed immediately?shikasd
05/20/2026, 12:08 PMmin
05/21/2026, 11:53 AMComposition objects, and a Composition composes @Composable functions via a Composer.
private fun applyChangesInLocked(changes: Changes) {
// ...
trace(traceName) {
val rememberManager = pendingPausedComposition?.rememberManager ?: rememberManager
applier.onBeginChanges()
changes.execute(slotStorage, applier, rememberManager, composer.errorContext)
applier.onEndChanges()
}
// ...
}
The Composer submits changes to the Composition, which schedules or executes them immediately. I’m guessing I can only materialise one tree from a Composition. The Composition then seems to execute the changes by passing them its slot table and the tree materialised from it while being composed. Have I got everything right?min
05/21/2026, 12:20 PMmin
05/21/2026, 12:20 PMmin
05/24/2026, 10:25 AMchanges.execute(slotStorage, applier, rememberManager, composer.errorContext) statement found in Composition.applyChanges. Change instances seem to run in the ‘apply phase’ and make changes to the slot table and the derived tree via the passed slotStorage and applier. Genuinely what on earth is going on? Could you please tell me the actual order of events?min
05/24/2026, 10:32 AMmin
05/24/2026, 10:36 AMshikasd
05/24/2026, 11:55 AMmin
05/24/2026, 12:37 PMComposer submits changes to its Composition
2. The Composition eventually relays those changes to
◦ Its slots, which constitute a serial representation of the composed tree,
◦ And trees to be kept in sync, each via its Applier
So in summary, this is the order of events, and
• A Composition is agnostic about the implementation detail of each materialised tree.
• A CompositionImpl drives one Applier, but there’s no technical limit to how many an arbitrary implementation of Composition can drive.
• What it means for a materialised tree to be kept in sync with the Composition is decided by its Applier, to which the Composition simply forwards all new changes.
These define the contract. Have I got everything right? Also if it’s more than what you can verify during the weekend, I can absolutely wait. Your help has been valuable the whole time, and I don’t mean to rush you in any waymin
05/24/2026, 5:52 PM