Push-pull functional reactive programming Conal Elliott 3 - - PowerPoint PPT Presentation

push pull functional reactive programming
SMART_READER_LITE
LIVE PREVIEW

Push-pull functional reactive programming Conal Elliott 3 - - PowerPoint PPT Presentation

Functional reactive programming Future values Improving values Unambiguous choice Push-pull functional reactive programming Conal Elliott 3 September, 2009 Haskell Symposium Conal Elliott Push-pull functional reactive programming


slide-1
SLIDE 1

Functional reactive programming Future values Improving values Unambiguous choice

Push-pull functional reactive programming

Conal Elliott 3 September, 2009 Haskell Symposium

Conal Elliott Push-pull functional reactive programming

slide-2
SLIDE 2

Functional reactive programming Future values Improving values Unambiguous choice

1 Functional reactive programming

Semantics Building blocks Refactoring

2 Future values

Class instances Future times

3 Improving values

Description and problems Improving

4 Unambiguous choice

Conal Elliott Push-pull functional reactive programming

slide-3
SLIDE 3

Functional reactive programming Future values Improving values Unambiguous choice Semantics Building blocks Refactoring

What is Functional Reactive Programming?

Composable dynamic values, . . . with simple & precise semantics. Continuous time (zoomable). Fine-grain, deterministic concurrency.

Conal Elliott Push-pull functional reactive programming

slide-4
SLIDE 4

Functional reactive programming Future values Improving values Unambiguous choice Semantics Building blocks Refactoring

Classic FRP – semantic model

Behaviors (signals) are flows of values, punctuated by event

  • ccurrences.

[ [Behaviorα] ] = T → α [ [Eventα] ] = [ T × α]

  • - monotonic

Conal Elliott Push-pull functional reactive programming

slide-5
SLIDE 5

Functional reactive programming Future values Improving values Unambiguous choice Semantics Building blocks Refactoring

Behaviors compose

time :: BehaviorT [ [time] ] = id pure :: α → Behaviorα [ [pure a] ] = λt → a = pure a (< ∗ >) :: Behaviorα→β → Behaviorα → Behaviorβ [ [fs < ∗ > as] ] = λt → (([ [fs] ] t) ([ [as] ] t)) = [ [fs] ] < ∗ > [ [as] ]

Conal Elliott Push-pull functional reactive programming

slide-6
SLIDE 6

Functional reactive programming Future values Improving values Unambiguous choice Semantics Building blocks Refactoring

Events compose

∅ :: Eventα [ [∅] ] = [ ] (⊕) :: Eventα → Eventα → Eventα [ [e ⊕ e′] ] = [ [e] ] ‘merge‘ [ [e′] ] fmap n :: (α → β) → Eventα → Eventβ [ [fmap f e] ] = map (λ(t, a) → (t, f a)) [ [e] ] = fmap (fmap f ) [ [e] ]

Conal Elliott Push-pull functional reactive programming

slide-7
SLIDE 7

Functional reactive programming Future values Improving values Unambiguous choice Semantics Building blocks Refactoring

Events punctuate behaviors

stepper :: α → Eventα → Behaviorα More generally, switcher :: Behaviorα → EventBehaviorα → Behaviorα

Conal Elliott Push-pull functional reactive programming

slide-8
SLIDE 8

Functional reactive programming Future values Improving values Unambiguous choice Semantics Building blocks Refactoring

Main idea of the paper: Behaviors are chains of simple phases

So represent as such: Behaviora = (T → a) × ( T × Behaviora) Catch: We need lazy expiration times.

Conal Elliott Push-pull functional reactive programming

slide-9
SLIDE 9

Functional reactive programming Future values Improving values Unambiguous choice Semantics Building blocks Refactoring

Generalize/simplify – Reactive values

Behaviorα = (T → α) × ( T × Behaviorα) Generalize: Reactiveβ = β × ( T × Reactiveβ)

  • - discrete reactive

And specialize: [ [TFunα] ] = T → α

  • - continuous non-reactive

Behavior = Reactive ◦ TFun This representation provides Functor and Applicative instances.

Conal Elliott Push-pull functional reactive programming

slide-10
SLIDE 10

Functional reactive programming Future values Improving values Unambiguous choice Semantics Building blocks Refactoring

TFun constant-folds

data Fun t a = K a | Fun (t → a) [ [Fun t a] ] = t → a data TFun = Fun T [ [K a] ] = const a [ [Fun f ] ] = f instance Functor (TFun t) where fmap f (K a) = K (f a) fmap f (Fun g) = Fun (f ◦ g) etc

Conal Elliott Push-pull functional reactive programming

slide-11
SLIDE 11

Functional reactive programming Future values Improving values Unambiguous choice Semantics Building blocks Refactoring

Generalize/simplify – Future values

Reactiveβ = β × ( T × Reactiveβ) becomes Futureγ = T × γ Reactiveβ = β × FutureReactiveβ

Conal Elliott Push-pull functional reactive programming

slide-12
SLIDE 12

Functional reactive programming Future values Improving values Unambiguous choice Semantics Building blocks Refactoring

Events are future reactives

Reactiveβ = β × FutureReactiveβ becomes Eventα = FutureReactiveα Reactiveβ = β × Eventβ

Conal Elliott Push-pull functional reactive programming

slide-13
SLIDE 13

Functional reactive programming Future values Improving values Unambiguous choice Semantics Building blocks Refactoring

Summarizing

Futureγ = T × γ Eventα = FutureReactiveα Reactiveβ = β × Eventβ Behavior = Reactive ◦ TFun data Fun t a = K a | Fun (t → a)

Conal Elliott Push-pull functional reactive programming

slide-14
SLIDE 14

Functional reactive programming Future values Improving values Unambiguous choice Class instances Future times

Future values are mostly easy

newtype Future α = Fut ( T , α) deriving (Functor, Applicative, Monad) For Applicative and Monad, the T monoid uses max and −∞.

Conal Elliott Push-pull functional reactive programming

slide-15
SLIDE 15

Functional reactive programming Future values Improving values Unambiguous choice Class instances Future times

What about Monoid? A first try:

(⊕) chooses the earlier of two futures: instance Monoid (Future α) where ∅ = Fut (∞, ⊥) ua@(Fut (ˆ ta, )) ⊕ ub@(Fut (ˆ tb, )) = if ˆ ta ˆ tb then ua else ub We’ll have to compare future times without knowing both fully. Even so, there’s a problem ...

Conal Elliott Push-pull functional reactive programming

slide-16
SLIDE 16

Functional reactive programming Future values Improving values Unambiguous choice Class instances Future times

(⊕) must be even lazier.

First try: ua@(Fut (ˆ ta, )) ⊕ ub@(Fut (ˆ tb, )) = if ˆ ta ˆ tb then ua else ub Produces no information until resolving ˆ ta ˆ tb. Consider (ua ⊕ ub) ⊕ uc, where uc is earliest. Oops. Solution: Fut (ˆ ta, a) ⊕ Fut (ˆ tb, b) = Fut (ˆ ta ‘min‘ ˆ tb, if ˆ ta ˆ tb then a else b) Can be optimized.

Conal Elliott Push-pull functional reactive programming

slide-17
SLIDE 17

Functional reactive programming Future values Improving values Unambiguous choice Class instances Future times

What are future times?

type T = Max (AddBounds (Improving T )) Max monoid for derived Applicative Future (and Monad) AddBounds for the Future and Max monoids Improving for partiality

Conal Elliott Push-pull functional reactive programming

slide-18
SLIDE 18

Functional reactive programming Future values Improving values Unambiguous choice Description and problems Improving

What are improving values?

Lazy values, as a monotonic sequence of lower bounds Invented by Warren Burton in the 1980s Operations for min and max Purely functional implementation

Conal Elliott Push-pull functional reactive programming

slide-19
SLIDE 19

Functional reactive programming Future values Improving values Unambiguous choice Description and problems Improving

Improving values have some problems.

Expensive to step through accumulated lower bounds Redundant traversal Needs a generator of lower bounds

Conal Elliott Push-pull functional reactive programming

slide-20
SLIDE 20

Functional reactive programming Future values Improving values Unambiguous choice Description and problems Improving

Can we improve on improving values?

What operations do we use on T ? exact :: Improvinga → a compareI :: Improvinga → a → Ordering min :: Improvinga → Improvinga → Improvinga () :: Improvinga → Improvinga → Bool Puzzle: Can exact and compareI implement min and ()? If so, data Improving a = Imp {exact :: a, compareI :: a → Ordering }

Conal Elliott Push-pull functional reactive programming

slide-21
SLIDE 21

Functional reactive programming Future values Improving values Unambiguous choice Description and problems Improving

Comparing improving values – dilemma

How to compare future times: ˆ ta ˆ tb? Two ideas: ab = compareI ˆ ta (exact ˆ tb) ≡ GT ba = compareI ˆ tb (exact ˆ ta) ≡ LT Which to try first? We can’t know beforehand.

Conal Elliott Push-pull functional reactive programming

slide-22
SLIDE 22

Functional reactive programming Future values Improving values Unambiguous choice

Try both

Same answer when defined, so try in parallel and take first answer ab ‘unamb‘ ba Referentially transparent? Yes: ab ‘unamb‘ ba ≡ ab ⊔ ba Crucial: ab and ba agree when defined.

Conal Elliott Push-pull functional reactive programming

slide-23
SLIDE 23

Functional reactive programming Future values Improving values Unambiguous choice

unamb is handy

parCommute op x y = (x ‘op‘ y) ‘unamb‘ (y ‘op‘ x) por = parCommute (∨) pand = parCommute (∧)

  • - handy with unamb

assuming :: Bool → a → a assuming True a = a assuming False = ⊥

Conal Elliott Push-pull functional reactive programming

slide-24
SLIDE 24

Functional reactive programming Future values Improving values Unambiguous choice

Symmetric short-circuiting

parAnnihilator op a x y = assuming (x ≡ a) a ‘unamb‘ assuming (y ≡ a) a ‘unamb‘ (x ‘op‘ y) por = parAnnihilator (∨) True pand = parAnnihilator (∧) False pmul = parAnnihilator (×) 0 pmin = parAnnihilator min minBound pmax = parAnnihilator max maxBound

Conal Elliott Push-pull functional reactive programming

slide-25
SLIDE 25

Functional reactive programming Future values Improving values Unambiguous choice

min is simple – almost

data Ordering = LT | EQ | GT deriving (Eq, Ord, Bounded, ...) compare (a ‘min‘ b) x = compare a x ‘min‘ compare b x Similarly, compareI (ˆ ta ‘min‘ ˆ tb) t = compareI ˆ ta t ‘min‘ compareI ˆ tb t Too strict. Consider exact ˆ ta < t < exact ˆ

  • tb. Easy fix, via unamb:

compareI (ˆ ta ‘min‘ ˆ tb) t = compareI ˆ ta t ‘pmin‘ compareI ˆ tb t

Conal Elliott Push-pull functional reactive programming

slide-26
SLIDE 26

Functional reactive programming Future values Improving values Unambiguous choice

Summary

Refactored FRP suggests hybrid data/function representation Data-driven but still pull-based, due to blocking threads Semantic determinacy saved, thanks to unambiguous choice

Conal Elliott Push-pull functional reactive programming

slide-27
SLIDE 27

Functional reactive programming Future values Improving values Unambiguous choice

Future work

Subtle RTS and/or laziness. Measure and tune, esp improving values & unamb. Useful for arrow-based FRP? More fun with unamb Event is fishy. No semantic TCM, monad assoc can fail. Extend caching to TFun.

Conal Elliott Push-pull functional reactive programming