<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Staticvar Learn</title><link>https://learn.staticvar.dev/</link><description>Recent content on Staticvar Learn</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><atom:link href="https://learn.staticvar.dev/index.xml" rel="self" type="application/rss+xml"/><item><title>A state object is a record chain</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/05-snapshots-and-observable-state/01-a-state-object-is-a-record-chain/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/05-snapshots-and-observable-state/01-a-state-object-is-a-record-chain/</guid><description>Status: A state object owning versioned records is Durable . The linked-list fields, snapshot-ID algorithm, and record-reuse helpers are Version-specific at the pinned revision.
Outcome Given a MutableState, you should be able to explain why the same object can return different values in different snapshots without copying every object it references.
The object owns versions, not a copied object graph StateObject is the snapshot module’s interface for an object with state records.</description></item><item><title>A state write targets observed scopes</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/06-invalidation-recomposition-skipping/01-a-state-write-targets-observed-scopes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/06-invalidation-recomposition-skipping/01-a-state-write-targets-observed-scopes/</guid><description>Status: A read creates an observation edge and a later write can target the scopes on that edge. That causal model is Durable . The queue names and handoff methods are Version-specific at the pinned AndroidX revision.
Outcome Name the recipient of a state change at each boundary: snapshot notification, known composition, observed restart scope, and recomposer work list. Say what has not happened yet.
The write does not invalidate the whole tree During composition, CompositionImpl.</description></item><item><title>A URL is a plan</title><link>https://learn.staticvar.dev/courses/how-the-web-works/01-the-journey/01-a-url-is-a-plan/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/how-the-web-works/01-the-journey/01-a-url-is-a-plan/</guid><description>When you type an address into a browser, you are not simply naming a page. You are giving the browser a compact plan: how to communicate, where to go, and what to ask for.
The parts of a URL Consider this address:
https://learn.staticvar.dev/courses/web?mode=quick#dns Each part has a job:
Part Example Meaning Scheme https The protocol and security expectations Host learn.staticvar.dev The named destination Path /courses/web The resource being requested Query mode=quick Optional inputs for the server Fragment dns A location within the returned page The fragment is special: browsers normally use it locally.</description></item><item><title>Applier operations are a tree protocol</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/10-from-changes-to-ui-behavior/01-applier-operations-and-change-application/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/10-from-changes-to-ui-behavior/01-applier-operations-and-change-application/</guid><description>Status: The target-tree contract is Durable . The operation classes and execution order below are Version-specific at the pinned snapshot.
Outcome Given a pending change, identify which object owns the mutation, where current points, and why a change list is not the UI tree.
current is a traversal cursor An Applier&amp;lt;N&amp;gt; owns operations against a target tree. down(child) moves the cursor into a child; up() returns to its parent. insertTopDown, insertBottomUp, remove, move, and clear mutate children of the current node.</description></item><item><title>From HTML to a page</title><link>https://learn.staticvar.dev/courses/how-the-web-works/02-servers-and-pages/01-from-html-to-page/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/how-the-web-works/02-servers-and-pages/01-from-html-to-page/</guid><description>The browser does more than display an HTML file. It parses several languages, combines their results, calculates geometry, and paints pixels.
The rendering pipeline DiagramExpandflowchart TD HTML[HTML bytes] --&amp;gt; DOM[Document tree] CSS[CSS bytes] --&amp;gt; CSSOM[Style rules] DOM --&amp;gt; Render[Render tree] CSSOM --&amp;gt; Render Render --&amp;gt; Layout[Layout] Layout --&amp;gt; Paint[Paint] Paint --&amp;gt; Screen[Pixels] HTML supplies meaning and structure. CSS supplies presentation rules. JavaScript can change both after the initial page has loaded.</description></item><item><title>Movable content carries identity across locations</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/09-moving-reusing-nesting-composition/01-movable-content-carries-identity/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/09-moving-reusing-nesting-composition/01-movable-content-carries-identity/</guid><description>Evidence legend: Durable marks a stable mental model; Version-specific marks behavior tied to the AndroidX pin below; Experimental marks a changing or transitional path.
A remember value normally follows its position in one composition. What if a screen changes from a row to a column, but the editor, focus, or scroll state must follow the content rather than the old branch? movableContentOf makes that relocation explicit: the call creates a tracked content identity, and a later call can claim the state and nodes that left another location.</description></item><item><title>Positional identity and explicit key groups</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/04-identity-keys-remember-lifecycle/01-positional-identity-and-explicit-key-groups/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/04-identity-keys-remember-lifecycle/01-positional-identity-and-explicit-key-groups/</guid><description>Status: The matching model is Durable . Generated integer keys and composer method names are Version-specific observations at the pinned revisions above. This is not a promise that every compiler release emits identical groups.
Outcome Given a conditional or loop, you should be able to predict when a remembered value stays attached to the same logical work and when it is matched to a different position.
A group has a place and, sometimes, data identity The compiler turns composable structure into groups consumed by Composer.</description></item><item><title>Side effects run after a successful apply</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/08-effects-and-retained-lifetimes/01-side-effect-after-apply/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/08-effects-and-retained-lifetimes/01-side-effect-after-apply/</guid><description>Status: The rule that a side effect must not publish an un-applied result is Durable . The precise dispatcher sequence below is Version-specific .
Outcome Explain why a SideEffect can safely update an object outside snapshots only after changes apply, and why DisposableEffect is a remembered observer rather than code that runs during the composable body.
The body records; apply dispatches Calling SideEffect { ... } does not run the lambda.</description></item><item><title>Source information becomes tooling data</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/11-tooling-multiplatform-performance-evolution/01-source-information-traces-and-observers/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/11-tooling-multiplatform-performance-evolution/01-source-information-traces-and-observers/</guid><description>Evidence legend: Durable marks a stable mental model; Version-specific marks behavior tied to the pins above; Experimental marks a tooling-only, opt-in, or changing surface.
A crash in measure does not carry the original Kotlin call stack through every composition operation. Instead, Compose can build a second, diagnostic path: the compiler leaves source metadata around groups, the runtime stores it, and tooling interprets it later.
Compiler markers are breadcrumbs, not a source map Version-specific The pinned compiler lowering accepts collectSourceInformation and traceMarkersEnabled switches.</description></item><item><title>The compiler/runtime/node pipeline</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/01-what-system-did-compose-build/01-the-compiler-runtime-node-pipeline/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/01-what-system-did-compose-build/01-the-compiler-runtime-node-pipeline/</guid><description>Status: The five boundaries are Durable . Method names and compiler output are Version-specific at the pinned revisions above. This lesson describes a source snapshot, not every released Compose artifact.
Release mapping: No released artifact is asserted here. Check the Compose Runtime release notes before mapping these private details to a Maven version.
Outcome You should be able to point to the owner of each step:
Kotlin source → compiler protocol → composition memory → applied changes → UI nodes That map is more useful than saying that Compose “builds a view.</description></item><item><title>The recomposition loop and frame clock</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/07-scheduling-and-recomposer/01-the-recomposition-loop-and-frame-clock/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/07-scheduling-and-recomposer/01-the-recomposition-loop-and-frame-clock/</guid><description>Status: The separation between scheduling, composition, and application is Durable . The state names, queues, and frame ordering below are Version-specific at the pinned AndroidX revision.
Outcome Given a state write, explain when it becomes recomposition work, when a frame is requested, and why recompose, applyChanges, and applyLateChanges are different calls.
A recomposer is a work-state machine Recomposer.State distinguishes inactive, idle, pending-work, and shutdown states. Its lock-protected lists hold snapshot invalidations, invalidated compositions, and work awaiting application (Recomposer.</description></item><item><title>What `@Composable` changes</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/02-the-compiler-runtime-protocol/01-what-composable-changes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/02-the-compiler-runtime-protocol/01-what-composable-changes/</guid><description>Status: The idea that @Composable changes a function’s type and supplies a composition context is Durable . The names and generated calls below are Version-specific at the pinned revisions.
Outcome You should be able to explain why this function cannot be called from an ordinary function:
@Composable fun Greeting(name: String) { Text(&amp;#34;Hello, $name&amp;#34;) } The short answer is not “the annotation turns on magic.” It changes the function’s type. A call now participates in a compiler/runtime protocol.</description></item><item><title>What the slot table stores</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/03-composition-memory-and-identity/01-what-the-slot-table-stores/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/03-composition-memory-and-identity/01-what-the-slot-table-stores/</guid><description>Status: The distinction between composition memory and rendered nodes is Durable . The gap-buffer layout and private class names are Version-specific at the pinned revision.
Outcome Explain what a group owns and what an anchor means after insertion.
Start with runtime memory, not a widget tree A composition runs the same source more than once. Between runs, the runtime needs to know which execution region is being revisited, where its values are stored, and how many target nodes belong to that region.</description></item><item><title>`ComposeNode` crosses into `LayoutNode`</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/10-from-changes-to-ui-behavior/02-compose-node-to-layout-node/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/10-from-changes-to-ui-behavior/02-compose-node-to-layout-node/</guid><description>Status: The create/use/update distinction is Durable . The current helper overloads, UI node properties, and Android construction path are Version-specific .
Outcome Given a node-producing composable, read the source-level create/use branch and use a pinned composition fixture to distinguish initial node properties from later updater work.
ComposeNode is a small protocol wrapper The pinned ComposeNode first checks that the current applier has the expected type, starts a node group, then chooses createNode(factory) while currentComposer.</description></item><item><title>Historical concurrent recomposition and current pausable composition</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/07-scheduling-and-recomposer/02-concurrent-and-pausable-composition/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/07-scheduling-and-recomposer/02-concurrent-and-pausable-composition/</guid><description>Status: “Calculate a change list, then apply it” is Durable . The public concurrent runner is removed at the pinned revision; current PausableComposition, PausedCompositionImpl, ShouldPauseCallback, and RecordingApplier details are Version-specific . The Experimental label below marks the removed, changing history—not a current Kotlin opt-in annotation.
Outcome Explain what may run away from the applier, where mutable-snapshot conflicts are detected, and why a paused composition is not usable until apply().</description></item><item><title>Invalidation can be conditional or imminent</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/06-invalidation-recomposition-skipping/02-conditional-and-imminent-invalidation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/06-invalidation-recomposition-skipping/02-conditional-and-imminent-invalidation/</guid><description>Status: “Invalidated” is not one timing category. The four outcomes are Version-specific names for a Durable distinction between queued and active work.
Outcome Interpret IGNORED, SCHEDULED, DEFERRED, or IMMINENT, and explain why a derived-state read can remain conditionally tracked.
Four outcomes The pinned InvalidationResult enum defines these meanings (Composer.kt):
Result Meaning in the pinned runtime IGNORED The scope is removed, not yet entered, or cannot recompose. SCHEDULED The composition is not composing; the invalidation is recorded for later work.</description></item><item><title>LaunchedEffect belongs to a keyed composition scope</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/08-effects-and-retained-lifetimes/02-launched-effect-and-scope-ownership/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/08-effects-and-retained-lifetimes/02-launched-effect-and-scope-ownership/</guid><description>Status: An effect coroutine owned by a composition point is Durable . Its parent context, cancellation exception, and lazy scope internals are Version-specific .
Outcome Given a LaunchedEffect or rememberCoroutineScope call, identify who owns the Job, what a key change means, and why callback-started work should use a remembered scope instead of using state as a launch trigger.
LaunchedEffect has a remembered owner At the pinned source, LaunchedEffect(key...) reads currentComposer.</description></item><item><title>Link-buffer storage and `LinkComposer`</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/03-composition-memory-and-identity/02-link-buffer-storage-and-linkcomposer/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/03-composition-memory-and-identity/02-link-buffer-storage-and-linkcomposer/</guid><description>Status: The two storage strategies are Version-specific . The link-buffer path is Experimental : this pinned source says it is disabled by default, and release notes still describe it as experimental.
Outcome Explain what changes when LinkComposer replaces GapComposer, and state exactly when the current feature flag may be set.
“LinkTable” is a path, not a replacement The Gerrit change is titled “Reimplement SlotTable as a link table.” The source package is composer.</description></item><item><title>Multiplatform behavior has boundaries</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/11-tooling-multiplatform-performance-evolution/02-multiplatform-concurrency-boundaries/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/11-tooling-multiplatform-performance-evolution/02-multiplatform-concurrency-boundaries/</guid><description>Evidence legend: Durable marks common semantics; Version-specific marks a pinned source-set implementation; Experimental marks a changing or host-dependent path.
“Common code” tells you which algorithm is shared. It does not tell you which lock, atomic primitive, thread identity, or frame host surrounds that algorithm. The safest multiplatform explanation has two layers: first the common contract, then each target&amp;rsquo;s actual implementation.
What is common Durable The common runtime defines the snapshot/composition machinery, an expect-based SnapshotThreadLocal, a synchronization abstraction, and the MonotonicFrameClock interface.</description></item><item><title>Reading Compose source as evidence</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/01-what-system-did-compose-build/02-reading-compose-source-as-evidence/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/01-what-system-did-compose-build/02-reading-compose-source-as-evidence/</guid><description>Status: The reading method is Durable . Conclusions about the pinned files are Version-specific . A test proves its inputs, source set, target, and assertions. It does not prove every private detail forever.
Outcome When you investigate one Compose mechanism, you should be able to say:
where the protocol is declared; which compiler code produces it; which runtime code consumes it; which test observes it; and what history says about its scope.</description></item><item><title>Reusable composition changes the node lifecycle</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/09-moving-reusing-nesting-composition/02-reusable-composition-and-node-lifecycle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/09-moving-reusing-nesting-composition/02-reusable-composition-and-node-lifecycle/</guid><description>Evidence legend: Durable marks a stable mental model; Version-specific marks behavior tied to the AndroidX pin below; Experimental marks a changing or transitional path.
Movable content answers “how do I keep this identity while its location changes?” Reuse answers “how do I avoid allocating a new compatible node for different content?” The second question deliberately has a different answer for remembered values: node structure may be recycled, while remembered slots are treated as invalid for the new content.</description></item><item><title>Sibling reorder, `joinKey`, and moving state</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/04-identity-keys-remember-lifecycle/02-sibling-reorder-joinkey-and-moving-state/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/04-identity-keys-remember-lifecycle/02-sibling-reorder-joinkey-and-moving-state/</guid><description>Status: State following a keyed sibling is Durable behavior. joinKey, JoinedKey, and the exact reconciliation paths are Version-specific at the pinned revisions. The link-buffer path remains Experimental where noted by the implementation.
Outcome After inserting, deleting, reversing, or shuffling siblings, you should be able to predict which remembered object follows each data item and explain the role of joinKey when a key has several parts.
The reorder problem is a matching problem Suppose each row creates a remembered token:</description></item><item><title>Snapshots isolate values</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/05-snapshots-and-observable-state/02-snapshots-isolate-values/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/05-snapshots-and-observable-state/02-snapshots-isolate-values/</guid><description>Status: A snapshot is an isolated view of snapshot-aware state, not a lock or a copied application graph. That model is Durable . The GlobalSnapshot, MutableSnapshot, and nested-snapshot classes are Version-specific at the pinned revision.
Outcome Given a state write inside a snapshot, you should be able to say who can see it now, who can see it after a child apply, and who can see it after the parent applies.</description></item><item><title>The hidden `Composer` and mask parameters</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/02-the-compiler-runtime-protocol/02-hidden-composer-and-mask-parameters/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/02-the-compiler-runtime-protocol/02-hidden-composer-and-mask-parameters/</guid><description>Status: A composable needs a composer context and change metadata to support the protocol. That division is Durable . Parameter counts, names, and bit positions are Version-specific .
Outcome Given a source declaration such as this one, you should be able to point at the hidden values and explain their jobs:
@Composable fun Greeting(name: String = &amp;#34;world&amp;#34;, punctuation: String = &amp;#34;!&amp;#34;) { Text(&amp;#34;Hello, $name$punctuation&amp;#34;) } The current compiler lowers the visible parameters, then appends a nullable Composer, one or more changed-mask integers, and default-mask integers when defaults need protocol handling.</description></item><item><title>The HTTP conversation</title><link>https://learn.staticvar.dev/courses/how-the-web-works/01-the-journey/02-http-conversation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/how-the-web-works/01-the-journey/02-http-conversation/</guid><description>HTTP is the language browsers and web servers use to exchange messages. Its core pattern is deliberately simple: a client sends a request, and a server returns a response.
A request has intent GET /courses/web HTTP/1.1 Host: learn.staticvar.dev Accept: text/html The method GET says what the client intends to do. The path identifies the resource. Headers add context such as the desired response format.
A response reports an outcome HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Content-Length: 4280 &amp;lt;!</description></item><item><title>`remember` is a slot cache</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/04-identity-keys-remember-lifecycle/03-remember-is-a-slot-cache/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/04-identity-keys-remember-lifecycle/03-remember-is-a-slot-cache/</guid><description>Status: remember as composition-local caching is Durable . Composer.cache, slot traversal, and the selected gap/link storage path are Version-specific . The link-buffer route is Experimental at this snapshot.
Outcome You should be able to explain why a remember calculation runs once, when a keyed calculation runs again, and why the cache belongs to composition memory rather than to the Kotlin function.
The cache protocol is small The public overloads in Composables.</description></item><item><title>A node update fans out into UI work</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/10-from-changes-to-ui-behavior/03-node-updates-measure-layout-and-draw/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/10-from-changes-to-ui-behavior/03-node-updates-measure-layout-and-draw/</guid><description>Status: Recomposition, remeasurement, relayout, and redraw are distinct Durable stages. The node-kind invalidation map and queue implementation are Version-specific .
Outcome Given a changed ComposeUiNode property or modifier element, predict which downstream phase can be requested—and which phases are not implied.
A modifier is a node chain, not only a value LayoutNode.modifier is a property update surface. Once attached, LayoutNode.applyModifier stores the new modifier, calls nodes.updateFrom(modifier), and updates parent data (LayoutNode.</description></item><item><title>Apply is a commit attempt</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/05-snapshots-and-observable-state/03-apply-is-a-commit-attempt/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/05-snapshots-and-observable-state/03-apply-is-a-commit-attempt/</guid><description>Status: Apply is a visibility and conflict boundary, not a recomposition command. That separation is Durable . The previous/current/applied comparison and SnapshotApplyResult classes are Version-specific at the pinned revision.
Outcome Given two mutable snapshots that write the same state object, you should be able to predict whether the second apply succeeds, fails, or asks a mutation policy to merge values.
Apply closes an isolation interval A mutable snapshot accumulates modified StateObjects.</description></item><item><title>Benchmark evidence is workload-shaped</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/11-tooling-multiplatform-performance-evolution/03-benchmark-evidence-is-workload-shaped/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/11-tooling-multiplatform-performance-evolution/03-benchmark-evidence-is-workload-shaped/</guid><description>Evidence legend: Durable marks a measurement principle; Version-specific marks a pinned workload or harness; Experimental marks a comparison that needs controlled reruns.
A benchmark number answers a narrow question: how did this named workload behave under this harness? The runtime benchmark module makes that narrowness visible. It measures time, and its base class also records group and slot counts; it does not turn a synthetic tree into an application-wide frame-time promise (ComposeBenchmarkBase.</description></item><item><title>Composition storage is runtime memory</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/01-what-system-did-compose-build/03-composition-storage-is-runtime-memory/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/01-what-system-did-compose-build/03-composition-storage-is-runtime-memory/</guid><description>Status: The storage/tree distinction is Durable . The selected buffer and class names are Version-specific at the pinned revision. The link-buffer path is Experimental at this revision.
Outcome You should be able to answer this question precisely:
If composition storage is not the UI tree, what job does it do?
It keeps the runtime’s memory of composition structure and values so later work can compare, restart, skip, and update the right places.</description></item><item><title>CompositionContext makes nesting one logical tree</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/09-moving-reusing-nesting-composition/03-composition-context-and-measure-time-subcomposition/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/09-moving-reusing-nesting-composition/03-composition-context-and-measure-time-subcomposition/</guid><description>Evidence legend: Durable marks a stable mental model; Version-specific marks behavior tied to the AndroidX pin below; Experimental marks a changing or transitional path.
A subcomposition is a separate Composition, but it should not become a separate universe. A child may need values from the parent, and a parent state write may need to invalidate the child. CompositionContext is the bridge: it preserves logical ownership while allowing a layout to calculate child content later than the parent content call.</description></item><item><title>Remember, retain, and saved state are different lifetimes</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/08-effects-and-retained-lifetimes/03-remember-retain-and-saved-lifetimes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/08-effects-and-retained-lifetimes/03-remember-retain-and-saved-lifetimes/</guid><description>Status: The distinction between slot, retained-memory, saved-state, and process lifetimes is Durable . The retention-store protocol and current release mapping are Version-specific .
Outcome Given a value and a destruction event, predict whether it is recreated, restored from memory, restored from saved state, or lost with the process—and name the owner that decides.
Four owners, four failure modes remember is composition memory. Its calculation is cached in a slot and reused while the remembered identity remains in the composition; when that group is forgotten, the slot value is no longer an owner of the value.</description></item><item><title>Stability becomes comparison metadata</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/06-invalidation-recomposition-skipping/03-stability-becomes-comparison-metadata/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/06-invalidation-recomposition-skipping/03-stability-becomes-comparison-metadata/</guid><description>Status: Stability is compiler/runtime protocol input, not reflection. Its promise model is Durable ; inferred categories, fields, comparisons, and mask positions are Version-specific .
Outcome Explain why a parameter gets equality or identity comparison, and describe dirty masks as per-parameter metadata rather than memorize their packing.
Inference is more than “stable or unstable” The pinned compiler represents stability as Certain, Runtime, Unknown, Parameter, or Combined (Stability.kt). Primitives, strings, functions, enums, and objects can be known stable; mutable backing properties can make a class unstable; generic and external types can remain runtime or uncertain.</description></item><item><title>Transformed calls and composable function references</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/02-the-compiler-runtime-protocol/03-transformed-calls-and-function-references/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/02-the-compiler-runtime-protocol/03-transformed-calls-and-function-references/</guid><description>Status: A call and a function reference are different compiler problems even when both eventually invoke composable code. That distinction is Durable . Adapter shapes, memoization, and feature detection are Version-specific .
Outcome You should be able to answer this question:
Why can Child(value) look like an ordinary call while ::Child needs an adapter?
A direct call is rewritten in the caller’s current composer context. A reference must be represented as a value with a callable type, exposing composer and change information while hiding synthetic default-mask details.</description></item><item><title>Composition calculates, then applies changes</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/01-what-system-did-compose-build/04-composition-calculates-applies/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/01-what-system-did-compose-build/04-composition-calculates-applies/</guid><description>Status: The calculation/application split is Durable . Method names and callback ordering are Version-specific at the pinned revision.
Outcome You should be able to explain why a successful composition calculation does not mean that the target tree has already changed.
Two phases, two questions Composition asks:
What operations should happen for this execution?
Application asks:
How should those operations mutate the target tree?
The pinned ControlledComposition makes this boundary explicit.</description></item><item><title>Evolution is a reading workflow</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/11-tooling-multiplatform-performance-evolution/04-evolution-is-a-reading-workflow/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/11-tooling-multiplatform-performance-evolution/04-evolution-is-a-reading-workflow/</guid><description>Evidence legend: Durable marks a reusable investigation method; Version-specific marks a pinned implementation or release entry; Experimental marks a flag, deprecation, proposal, or transitional path.
Compose internals move. Ask each source what it can prove: tests/generated artifacts bound behavior; history explains transitions; release notes establish shipping; design docs preserve historical intent and terminology but may lag; roadmaps show intent only.
Use the evidence ladder Use this precedence: pinned implementation → tests/generated evidence → history → release notes → design docs → roadmap.</description></item><item><title>Groups, restart scopes, and source keys</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/02-the-compiler-runtime-protocol/04-groups-restart-scopes-and-source-keys/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/02-the-compiler-runtime-protocol/04-groups-restart-scopes-and-source-keys/</guid><description>Status: Groups mark protocol boundaries that let the runtime reconcile control flow or restart a region. That mental model is Durable . Which calls are emitted, and which groups are elided, are Version-specific .
Outcome You should be able to explain three different generated structures:
a function-level restart group; a replace group around a conditional branch; and no group around a non-restartable function whose surrounding control flow is already safe.</description></item><item><title>Mutation policies decide equivalence</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/05-snapshots-and-observable-state/04-mutation-policies-decide-equivalence/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/05-snapshots-and-observable-state/04-mutation-policies-decide-equivalence/</guid><description>Status: A mutation policy defines the state layer’s notion of equivalence and optional conflict merge. That role is Durable . The stock implementations and exact merge path are Version-specific at the pinned revision.
Outcome Given two assignments or two competing snapshot writes, you should be able to predict when a policy treats them as equivalent and when it permits a merge.
Equivalence is a state decision SnapshotMutationPolicy&amp;lt;T&amp;gt; has two operations.</description></item><item><title>One state change reaches pixels and hit paths</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/10-from-changes-to-ui-behavior/04-one-state-change-to-pixels-and-hit-path/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/10-from-changes-to-ui-behavior/04-one-state-change-to-pixels-and-hit-path/</guid><description>Status: The separation of recomposition, remeasurement, relayout, and redraw is Durable . The exact UI and pointer traversal below is Version-specific .
Outcome Trace one observed state write without saying “Compose redraws.” Name the boundary at each step and identify which steps may be skipped.
Five different events Keep the names separate: recomposition runs invalidated composition code; apply mutates the target tree; remeasurement recalculates sizes; relayout places already-measured nodes; and redraw refreshes pixels or layers.</description></item><item><title>Remembered, forgotten, and abandoned objects</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/04-identity-keys-remember-lifecycle/04-remembered-forgotten-and-abandoned/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/04-identity-keys-remember-lifecycle/04-remembered-forgotten-and-abandoned/</guid><description>Status: The distinction between Durable remembered, forgotten, and abandoned outcomes comes from the RememberObserver contract. Callback threading and dispatcher internals are Version-specific at the pinned revision.
Outcome Given a remembered object and a composition event, you should be able to predict whether onRemembered, onForgotten, or onAbandoned is the relevant callback—and which callback is not justified.
Three outcomes, three questions A RememberObserver is not notified when its constructor runs. It is notified when the composition has a lifecycle result for the remembered slot.</description></item><item><title>Retention has its own store and observer lifecycle</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/08-effects-and-retained-lifetimes/04-retained-store-observers-and-effects/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/08-effects-and-retained-lifetimes/04-retained-store-observers-and-effects/</guid><description>Status: Retention needs an owner beyond the slot table and therefore has a distinct callback vocabulary: Durable . Exact store handoffs, callback order, and lint enforcement are Version-specific .
Outcome Trace a retained object through successful retention, composition exit, restoration or retirement, and cleanup. Explain why RetainedEffect is not just DisposableEffect with a longer delay.
The store owns the gap after forgetting RetainedValuesStore defines the handoff around transient removal. Before owned content exits, onContentExitComposition tells the store to prepare.</description></item><item><title>Skipping is a decision, not a guarantee</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/06-invalidation-recomposition-skipping/04-skipping-is-a-decision-not-a-guarantee/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/06-invalidation-recomposition-skipping/04-skipping-is-a-decision-not-a-guarantee/</guid><description>Status: Restartability gives the runtime a callable scope to revisit. Execution is a separate Durable decision; gates and strong-skipping defaults are Version-specific .
Outcome Explain why a restartable composable can execute, skip, or be deliberately non-skippable.
Restartable is a return path A restart group records a RecomposeScopeImpl and a callback that can re-enter it. The pinned compiler emits startRestartGroup, a body, and endRestartGroup()?.updateScope (ComposableFunctionBodyTransformer.kt). That answers “can this region restart?</description></item><item><title>SubcomposeLayout turns slots into a reuse pool</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/09-moving-reusing-nesting-composition/04-subcompose-slots-precomposition-and-pausing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/09-moving-reusing-nesting-composition/04-subcompose-slots-precomposition-and-pausing/</guid><description>Evidence legend: Durable marks a stable mental model; Version-specific marks behavior tied to the AndroidX pin below; Experimental marks a changing or transitional path.
SubcomposeLayoutState is not just a map from IDs to lambdas. At the pinned source, LayoutNodeSubcompositionsState keeps virtual child LayoutNodes and a NodeState for each composition. Its child list has exactly three storage ranges: active children, a reusable middle section, and precomposed children waiting at the end (SubcomposeLayout.</description></item><item><title>Apply success, failure, and event dispatch</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/04-identity-keys-remember-lifecycle/05-apply-success-failure-and-event-dispatch/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/04-identity-keys-remember-lifecycle/05-apply-success-failure-and-event-dispatch/</guid><description>Status: The separation between composition, application, and abandonment is Durable . RememberManager, RememberEventDispatcher, and their exact queues are Version-specific at the pinned AndroidX revision. Paused-composition hooks are Experimental context, not ordinary remember semantics.
Outcome You should be able to trace a remembered object through change calculation, apply, observer dispatch, side-effect dispatch, and the failure path that produces onAbandoned.
RememberManager is the apply-phase inbox The internal RememberManager receives events while changes execute.</description></item><item><title>From a node operation to LayoutNode</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/01-what-system-did-compose-build/05-from-node-operation-to-layoutnode/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/01-what-system-did-compose-build/05-from-node-operation-to-layoutnode/</guid><description>Status: The distinction between group calls and node calls is Durable . ComposeUiNode and LayoutNode details are Version-specific at the pinned revision.
Outcome You should be able to trace one target-node insertion and explain why a wrapper composable can run without inserting anything.
Group work is not node work The Composer protocol has both group operations and node operations. A group records logical composition structure. A node operation asks the applier-owned tree to create, retain, or update a target object.</description></item><item><title>Reads become observation edges</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/05-snapshots-and-observable-state/05-reads-become-observation-edges/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/05-snapshots-and-observable-state/05-reads-become-observation-edges/</guid><description>Status: Turning a read into an observation edge is Durable . The composition maps, reader flags, apply queue, and executor behavior are Version-specific at the pinned revision.
Outcome After a state read, you should be able to identify the recorded edge and distinguish it from the later work that a scheduler may perform.
A read has an owner SnapshotMutableState documents the central boundary: reading value during a composable subscribes the current RecomposeScope to that value, while writes are transacted through snapshots (SnapshotMutableState.</description></item><item><title>Replace, movable, and reusable groups</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/02-the-compiler-runtime-protocol/05-replace-movable-and-reusable-groups/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/02-the-compiler-runtime-protocol/05-replace-movable-and-reusable-groups/</guid><description>Status: The three roles—replace a control-flow region, move keyed content, and reuse content or nodes—are Durable protocol distinctions. Their method names and lifecycle details are Version-specific at the pinned revision.
Outcome When you see a group call, ask what kind of continuity it promises:
Group Continuity question Replace Can this region only be inserted, removed, or replaced? Movable Can this keyed content move to another position while keeping identity? Reusable Can existing content or nodes be prepared for a different data key?</description></item><item><title>`derivedStateOf` tracks dependencies and values</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/05-snapshots-and-observable-state/06-derived-state-tracks-dependencies-and-values/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/05-snapshots-and-observable-state/06-derived-state-tracks-dependencies-and-values/</guid><description>Status: Derived state as cached state plus dependency tracking is Durable . ResultRecord, nested read levels, readable hashes, and observer maps are Version-specific at the pinned revision.
Outcome Given a derivedStateOf calculation, you should be able to explain what is cached, which state objects are dependencies, and why an unchanged derived result can avoid a downstream observation change.
It is a state object with a calculation record derivedStateOf { .</description></item><item><title>Follow one state change through the pipeline</title><link>https://learn.staticvar.dev/courses/jetpack-compose-internals/01-what-system-did-compose-build/06-follow-a-state-change/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/courses/jetpack-compose-internals/01-what-system-did-compose-build/06-follow-a-state-change/</guid><description>Status: The separation between observed state, recomposition calculation, and application is Durable . The controlled API sequence below is Version-specific at the pinned revision.
Outcome You should be able to predict which event changes during a state update:
the state object is written; an observed scope is made eligible for recomposition; composition calculates pending operations; or the applier mutates the target tree. These are related events. They are not one event called “recomposition.</description></item><item><title>About Staticvar Learn</title><link>https://learn.staticvar.dev/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/about/</guid><description>Staticvar Learn is a free, public library of written lessons for people who want to understand how things work—not merely memorize a sequence of clicks.
Built for careful reading Written lessons let you choose the pace. You can pause over a diagram, copy an example, follow a reference, or return to one exact paragraph later. Every course is structured as short chapters and focused lessons.
Open by default There is no account, subscription, or progress system.</description></item><item><title>Evidence labels</title><link>https://learn.staticvar.dev/glossary/evidence-labels/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/glossary/evidence-labels/</guid><description>Evidence labels tell you how fresh a claim is and what kind of evidence supports it. They do not describe public API stability.
The labels Durable — a core mental model that is unlikely to change even when implementation details do. Version-specific — accurate for the cited source revision. Names, ordering, and private details may differ in another revision. Experimental — actively changing, transitional, or not enabled by default. Treat it as a direction to investigate, not settled behavior.</description></item><item><title>Search</title><link>https://learn.staticvar.dev/search/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn.staticvar.dev/search/</guid><description/></item></channel></rss>