Loading packages/SystemUI/frp/Android.bp→packages/SystemUI/utils/kairos/Android.bp +4 −4 Original line number Diff line number Diff line Loading @@ -20,9 +20,9 @@ package { } java_library { name: "kt-frp", name: "kairos", host_supported: true, kotlincflags: ["-opt-in=com.android.systemui.experimental.frp.ExperimentalFrpApi"], kotlincflags: ["-opt-in=com.android.systemui.kairos.ExperimentalFrpApi"], srcs: ["src/**/*.kt"], static_libs: [ "kotlin-stdlib", Loading @@ -31,7 +31,7 @@ java_library { } java_test { name: "kt-frp-test", name: "kairos-test", optimize: { enabled: false, }, Loading @@ -39,7 +39,7 @@ java_test { "test/**/*.kt", ], static_libs: [ "kt-frp", "kairos", "junit", "kotlin-stdlib", "kotlin-test", Loading packages/SystemUI/frp/OWNERS→packages/SystemUI/utils/kairos/OWNERS +0 −0 File moved. View file packages/SystemUI/frp/README.md→packages/SystemUI/utils/kairos/README.md +4 −4 Original line number Diff line number Diff line # kt-frp # Kairos A functional reactive programming (FRP) library for Kotlin. Loading @@ -13,12 +13,12 @@ FRP exposes an API that should be familiar to those versed in Kotlin `Flow`. ### Details for nerds `kt-frp` implements an applicative / monadic flavor of FRP, using a push-pull `Kairos` implements an applicative / monadic flavor of FRP, using a push-pull methodology to allow for efficient updates. "Real" functional reactive programming should be specified with denotational semantics ([wikipedia](https://en.wikipedia.org/wiki/Denotational_semantics)): you can view the semantics for `kt-frp` [here](docs/semantics.md). you can view the semantics for `Kairos` [here](docs/semantics.md). ## Usage Loading Loading @@ -61,4 +61,4 @@ will tear-down all effects and obervers running within the lambda. ## Resources - [Cheatsheet for those coming from Kotlin Flow](docs/flow-to-frp-cheatsheet.md) - [Cheatsheet for those coming from Kotlin Flow](docs/flow-to-kairos-cheatsheet.md) packages/SystemUI/frp/docs/flow-to-frp-cheatsheet.md→packages/SystemUI/utils/kairos/docs/flow-to-kairos-cheatsheet.md +13 −13 Original line number Diff line number Diff line # From Flows to FRP # From Flows to Kairos ## Key differences * FRP evaluates all events (`TFlow` emissions + observers) in a transaction. * Kairos evaluates all events (`TFlow` emissions + observers) in a transaction. * FRP splits `Flow` APIs into two distinct types: `TFlow` and `TState` * Kairos splits `Flow` APIs into two distinct types: `TFlow` and `TState` * `TFlow` is roughly equivalent to `SharedFlow` w/ a replay cache that exists for the duration of the current FRP transaction and shared with exists for the duration of the current Kairos transaction and shared with `SharingStarted.WhileSubscribed()` * `TState` is roughly equivalent to `StateFlow` shared with `SharingStarted.Eagerly`, but the current value can only be queried within a FRP transaction, and the value is only updated at the end of the a Kairos transaction, and the value is only updated at the end of the transaction * FRP further divides `Flow` APIs based on how they internally use state: * Kairos further divides `Flow` APIs based on how they internally use state: * **FrpTransactionScope:** APIs that internally query some state need to be performed within an FRP transaction performed within an Kairos transaction * this scope is available from the other scopes, and from most lambdas passed to other FRP APIs passed to other Kairos APIs * **FrpStateScope:** APIs that internally accumulate state in reaction to events need to be performed within an FRP State scope (akin to a Loading Loading @@ -126,8 +126,8 @@ has emitted at least once. This often bites developers. As a workaround, developers generally append `.onStart { emit(initialValue) }` to the `Flows` that don't immediately emit. FRP avoids this gotcha by forcing usage of `TState` for `combine`, thus ensuring that there is always a current value to be combined for each input. Kairos avoids this gotcha by forcing usage of `TState` for `combine`, thus ensuring that there is always a current value to be combined for each input. ## collect { … } Loading Loading @@ -158,8 +158,8 @@ tFlow.map { tState.sample() } #### Explanation To keep all state-reads consistent, the current value of a TState can only be queried within an FRP transaction, modeled with `FrpTransactionScope`. Note that both `FrpStateScope` and `FrpBuildScope` extend `FrpTransactionScope`. queried within a Kairos transaction, modeled with `FrpTransactionScope`. Note that both `FrpStateScope` and `FrpBuildScope` extend `FrpTransactionScope`. ### I want to sample a TFlow Loading Loading @@ -198,7 +198,7 @@ simultaneous emissions within the same transaction. #### Explanation Under FRP's rules, a `TFlow` may only emit up to once per transaction. This Under Kairos's rules, a `TFlow` may only emit up to once per transaction. This means that if we are merging two or more `TFlows` that are emitting at the same time (within the same transaction), the resulting merged `TFlow` must emit a single value. The lambda argument allows the developer to decide what to do in Loading packages/SystemUI/frp/docs/semantics.md→packages/SystemUI/utils/kairos/docs/semantics.md +3 −3 Original line number Diff line number Diff line # FRP Semantics `kt-frp`'s pure API is based off of the following denotational semantics `Kairos`'s pure API is based off of the following denotational semantics ([wikipedia](https://en.wikipedia.org/wiki/Denotational_semantics)). The semantics model `kt-frp` types as time-varying values; by making `Time` a The semantics model `Kairos` types as time-varying values; by making `Time` a first-class value, we can define a referentially-transparent API that allows us to reason about the behavior of the pure FRP combinators. This is to reason about the behavior of the pure `Kairos` combinators. This is implementation-agnostic; we can compare the behavior of any implementation with expected behavior denoted by these semantics to identify bugs. Loading Loading
packages/SystemUI/frp/Android.bp→packages/SystemUI/utils/kairos/Android.bp +4 −4 Original line number Diff line number Diff line Loading @@ -20,9 +20,9 @@ package { } java_library { name: "kt-frp", name: "kairos", host_supported: true, kotlincflags: ["-opt-in=com.android.systemui.experimental.frp.ExperimentalFrpApi"], kotlincflags: ["-opt-in=com.android.systemui.kairos.ExperimentalFrpApi"], srcs: ["src/**/*.kt"], static_libs: [ "kotlin-stdlib", Loading @@ -31,7 +31,7 @@ java_library { } java_test { name: "kt-frp-test", name: "kairos-test", optimize: { enabled: false, }, Loading @@ -39,7 +39,7 @@ java_test { "test/**/*.kt", ], static_libs: [ "kt-frp", "kairos", "junit", "kotlin-stdlib", "kotlin-test", Loading
packages/SystemUI/frp/README.md→packages/SystemUI/utils/kairos/README.md +4 −4 Original line number Diff line number Diff line # kt-frp # Kairos A functional reactive programming (FRP) library for Kotlin. Loading @@ -13,12 +13,12 @@ FRP exposes an API that should be familiar to those versed in Kotlin `Flow`. ### Details for nerds `kt-frp` implements an applicative / monadic flavor of FRP, using a push-pull `Kairos` implements an applicative / monadic flavor of FRP, using a push-pull methodology to allow for efficient updates. "Real" functional reactive programming should be specified with denotational semantics ([wikipedia](https://en.wikipedia.org/wiki/Denotational_semantics)): you can view the semantics for `kt-frp` [here](docs/semantics.md). you can view the semantics for `Kairos` [here](docs/semantics.md). ## Usage Loading Loading @@ -61,4 +61,4 @@ will tear-down all effects and obervers running within the lambda. ## Resources - [Cheatsheet for those coming from Kotlin Flow](docs/flow-to-frp-cheatsheet.md) - [Cheatsheet for those coming from Kotlin Flow](docs/flow-to-kairos-cheatsheet.md)
packages/SystemUI/frp/docs/flow-to-frp-cheatsheet.md→packages/SystemUI/utils/kairos/docs/flow-to-kairos-cheatsheet.md +13 −13 Original line number Diff line number Diff line # From Flows to FRP # From Flows to Kairos ## Key differences * FRP evaluates all events (`TFlow` emissions + observers) in a transaction. * Kairos evaluates all events (`TFlow` emissions + observers) in a transaction. * FRP splits `Flow` APIs into two distinct types: `TFlow` and `TState` * Kairos splits `Flow` APIs into two distinct types: `TFlow` and `TState` * `TFlow` is roughly equivalent to `SharedFlow` w/ a replay cache that exists for the duration of the current FRP transaction and shared with exists for the duration of the current Kairos transaction and shared with `SharingStarted.WhileSubscribed()` * `TState` is roughly equivalent to `StateFlow` shared with `SharingStarted.Eagerly`, but the current value can only be queried within a FRP transaction, and the value is only updated at the end of the a Kairos transaction, and the value is only updated at the end of the transaction * FRP further divides `Flow` APIs based on how they internally use state: * Kairos further divides `Flow` APIs based on how they internally use state: * **FrpTransactionScope:** APIs that internally query some state need to be performed within an FRP transaction performed within an Kairos transaction * this scope is available from the other scopes, and from most lambdas passed to other FRP APIs passed to other Kairos APIs * **FrpStateScope:** APIs that internally accumulate state in reaction to events need to be performed within an FRP State scope (akin to a Loading Loading @@ -126,8 +126,8 @@ has emitted at least once. This often bites developers. As a workaround, developers generally append `.onStart { emit(initialValue) }` to the `Flows` that don't immediately emit. FRP avoids this gotcha by forcing usage of `TState` for `combine`, thus ensuring that there is always a current value to be combined for each input. Kairos avoids this gotcha by forcing usage of `TState` for `combine`, thus ensuring that there is always a current value to be combined for each input. ## collect { … } Loading Loading @@ -158,8 +158,8 @@ tFlow.map { tState.sample() } #### Explanation To keep all state-reads consistent, the current value of a TState can only be queried within an FRP transaction, modeled with `FrpTransactionScope`. Note that both `FrpStateScope` and `FrpBuildScope` extend `FrpTransactionScope`. queried within a Kairos transaction, modeled with `FrpTransactionScope`. Note that both `FrpStateScope` and `FrpBuildScope` extend `FrpTransactionScope`. ### I want to sample a TFlow Loading Loading @@ -198,7 +198,7 @@ simultaneous emissions within the same transaction. #### Explanation Under FRP's rules, a `TFlow` may only emit up to once per transaction. This Under Kairos's rules, a `TFlow` may only emit up to once per transaction. This means that if we are merging two or more `TFlows` that are emitting at the same time (within the same transaction), the resulting merged `TFlow` must emit a single value. The lambda argument allows the developer to decide what to do in Loading
packages/SystemUI/frp/docs/semantics.md→packages/SystemUI/utils/kairos/docs/semantics.md +3 −3 Original line number Diff line number Diff line # FRP Semantics `kt-frp`'s pure API is based off of the following denotational semantics `Kairos`'s pure API is based off of the following denotational semantics ([wikipedia](https://en.wikipedia.org/wiki/Denotational_semantics)). The semantics model `kt-frp` types as time-varying values; by making `Time` a The semantics model `Kairos` types as time-varying values; by making `Time` a first-class value, we can define a referentially-transparent API that allows us to reason about the behavior of the pure FRP combinators. This is to reason about the behavior of the pure `Kairos` combinators. This is implementation-agnostic; we can compare the behavior of any implementation with expected behavior denoted by these semantics to identify bugs. Loading