How FRP Gets Its Core - PowerPoint PPT Presentation

1 / 55
About This Presentation
Title:

How FRP Gets Its Core

Description:

Hard to compose different domains. A robot which receives commands from keyboard ... Compose input types. class (GuiInput in, ConInput in) = GCInput in ... – PowerPoint PPT presentation

Number of Views:32
Avg rating:3.0/5.0
Slides: 56
Provided by: zhanyo
Category:
Tags: frp | compose | core | gets

less

Transcript and Presenter's Notes

Title: How FRP Gets Its Core


1
How FRP Gets Its Core
Official Graduate Student Talk
  • Design Decisions andImplementation
    Techniquesfor Functional Reactive Programming

Zhanyong Wan10/31/2000 Yale University Advisor
Paul Hudak
2
Outline
  • Background
  • Design implementation of core FRP
  • Clocked events
  • User implicit vs. explicit
  • Sustainment
  • Modular input
  • Memoization
  • Task monad
  • Future work

3
What Is FRP?
  • Functional Reactive Programming (FRP)
  • General framework for reactive hybrid systems
  • Interactive animation -- Fran
  • Robotics -- Frob
  • Soccer -- RoboCup
  • GUI -- FranTk, Frappe
  • Other control systems -- Fr
  • Functional
  • Higher-order functions
  • Polymorphism
  • Static typing
  • Pure
  • High-level, declarative
  • Time is continuous
  • Core FRP
  • Attempt to unify the dialects

4
Understand FRP
  • Behaviors
  • Reactive, continuous-time-varying values
  • time, temperature, sin time
  • Events
  • Streams of discrete event occurrences
  • lbp, when (temperature gt threshold)
  • Switching
  • sin time until when (temperature gt threshold)
    -gt cos time
  • Combinators
  • Behaviors and events are both first-class.
  • when Behavior Bool -gt Event ()
  • until Behavior a -gt Event (Behavior a) -gt
  • Behavior a
  • (-gt) Event a -gt b -gt Event b

5
A Discrete Implementation
  • Domain-specific language (DSL) embedded in
    Haskell
  • Library of Haskell data types and functions
  • Signals as stream transformers
  • type Behavior a UserAction -gt Time -gt a
  • type Event a UserAction -gt Time -gt Maybe
    a
  • Combinators as higher-order functions on signals
  • until Behavior a -gt Event (Behavior a) -gt
    Behavior a
  • (-gt) Event a -gt b -gt Event b
  • Run-time engine

FRP program
input streams
behavior
Run-timeEngine
behavior
result streams
event
6
Outline
  • Background
  • Design implementation of core FRP
  • Clocked events
  • User implicit vs. explicit
  • Sustainment
  • Modular input
  • Memoization
  • Task monad
  • Future work

7
Legend
  • Design decisions
  • Implementation techniques

D
I
8
Clocked Events -- Motivation
D
  • Motivation
  • We can apply lifted functions to behaviors
  • lift2 (a -gt b -gt c) -gt Behavior a -gt Behavior
    b -gt Behavior c
  • lift2 () b1 b2 ?
  • We can not apply lifted functions to events
  • lift2 () e1 e2 ?
  • e1 and e2 are not guaranteed to be synchronous

9
Clocked Events -- Implementation
I
  • Clocked events
  • newtype CEvent c a
  • CEvent (UserAction -gt Time -gt Maybe a)
  • Two events w/ same clock are guaranteed to be
    synchronous
  • lift2 (a -gt b -gt c) -gt CEvent clk a -gt
  • CEvent clk b -gt CEvent clk c
  • Events w/ different clocks are incompatible
  • e1 CEvent C1 Int
  • e2, e3 CEvent C2 Int
  • lift2 () e1 e2 ?
  • lift2 () e2 e3 ?

10
Ambiguously Clocked Events
SPAM
D
  • Const behaviors
  • lift0 a -gt Behavior a
  • b1, b2 Behavior Int
  • b1
  • b2 lift2 () b1 (lift0 5)
  • Const clocked events
  • e1, e2 CEvent C Int
  • e3, e4 CEvent C Int
  • e1
  • e2 lift2 () e1 (lift0 5)
  • e3
  • e4 lift2 () e3 (lift0 5)
  • lift0 produces an ambiguously clocked event
  • lift0 a -gt CEvent clk a
  • newtype CEvent c a
  • CEvent (UserAction -gt Time -gt Maybe a)
  • AmbCEvent a

11
Overloading Lifting Combinators
I
  • Lifting should be overloaded
  • for behaviors
  • for clocked events
  • Haskell type class provides nice support for
    overloading
  • class Zippable z where
  • lift0 a -gt z a
  • lift1 (a-gtb) -gt z a -gt z b
  • lift2 (a-gtb-gtc) -gt z a -gt z b -gt z c
  • instance Zippable Behavior where
  • instance Zippable (CEvent clk) where

12
Outline
  • Background
  • Design implementation of core FRP
  • Clocked events
  • User implicit vs. explicit
  • Sustainment
  • Modular input
  • Memoization
  • Task monad
  • Future work

13
User Aging the Question
D
  • Question What should a mean?
  • keyCount 0 stepAccum key -gt (1)
  • a 0 until lbp -gt keyCount
  • Answer 1 only key presses after lbp count.
  • Answer 2 all key presses count.
  • Which answer do we want to be correct?

14
User Aging the Question
D
  • Question What should a mean?
  • keyCount 0 stepAccum key -gt (1)
  • a 0 until lbp -gt keyCount
  • Answer 1 only key presses after lbp count.
  • Answer 2 all key presses count.
  • Which answer do we want to be correct?
  • Both!

15
Explicit User Aging
D
  • Age user explicitly
  • User is the stream of user actions
  • Make user an explicit parameter
  • key User -gt Event Char
  • lbp User -gt Event ()
  • When switching, the after-behavior receives an
    aged user
  • The programmer decides to age the user or not
  • keyCount u 0 stepAccum key u -gt (1)
  • a1 u 0 until lbp u -gt (\u -gt keyCount u)
  • a2 u 0 until lbp u -gt (\u -gt keyCount u)
  • Used by Conal Elliott in Fran

u original user
u aged user
16
Problems of the Explicit Approach
D
  • Tedious
  • Space leak
  • User is a data structure representing all user
    inputs
  • The program can hold on to the original User
  • a2 u 0 until lbp u -gt (\u -gt keyCount u)
  • Time leak
  • Catch-up computation
  • Unbounded response time
  • Not good enough!

17
Implicit User Aging
D
  • User no longer explicit
  • Age User implicitly
  • until always ages the User
  • a1 0 until lbp -gt keyCount
  • No space leak
  • No time leak
  • But what if we dont want to age the User?

18
Implicit User Aging (contd)
D
  • What if we dont want to age the User?
  • Solution 1
  • keyCount n n stepAccum key -gt (1)
  • a2 0 until (lbp snapshot_ keyCount 0) gt
    (\n -gt keyCount n)
  • Obscured code
  • Not expressive enough

19
Implicit User Aging (contd)
  • What if we dont want to age the User?
  • Solution 2
  • a2 letrun keyCount 0 stepAccum key -gt (1)
  • in 0 until lbp -gt keyCount
  • FRP is embedded in Haskell
  • Can not define construct that introduces binding

letrun b foo in barb
runningIn Behavior a -gt (Behavior a -gt
Behavior b) -gt Behavior b a2 (0
stepAccum key -gt (1)) runningIn
(\keyCount -gt 0 until lbp -gt keyCount)
20
Outline
  • Background
  • Design implementation of core FRP
  • Clocked events
  • User implicit vs. explicit
  • Sustainment
  • Modular input
  • Memoization
  • Task monad
  • Future work

21
Implementation of runningIn
I
  • A behavior/event/cevent can run in a
    behavior/event/cevent
  • 33 9 combinations!
  • runningIn needs to be overloaded
  • Multi-parameter type class
  • class Run a b where
  • runningIn a -gt (a -gt b) -gt b
  • instance Run Behavior Behavior where
  • instance Run Behavior Event where
  • instance Run Behavior (CEvent c) where
  • instance Run (CEvent c) (CEvent c) where
  • 9 instance declarations

22
Implementation of runningIn (contd)
I
  • Not neat
  • n2 instances are too many
  • What if we add a new kind of signal?
  • An Improvement
  • class ImpAs a b a -gt b where
  • -- a can be implemented as b
  • toImp a -gt b
  • fromImp b -gt a
  • type GB a UserAction -gt Time -gt a
  • instance ImpAs (Behavior a) (GB a) where
  • instance ImpAs (Event a) (GB (Maybe a)) where
  • instance ImpAs (CEvent clk a) (GB (Maybe a))
    where
  • instance (ImpAs a (GB b), ImpAs c (GB d)) gt Run
    a c where
  • Now only (n 1) instances

23
Outline
  • Background
  • Design implementation of core FRP
  • Clocked events
  • User implicit vs. explicit
  • Sustainment
  • Modular input
  • Memoization
  • Task monad
  • Future work

24
Input in Original FRP
D
  • User input type hard-wired
  • type UserAction
  • type Behavior a UserAction -gt Time -gt a
  • type Event a UserAction -gt Time -gt Maybe
    a
  • Type UserAction depends on the application domain
  • Animation and GUI
  • UserAction mouse movement mouse clicks
    keyboard clicks
  • Robotics
  • UserAction vision bumper reading reading
    of other sensors
  • Other domains
  • UserAction

25
Problems of the User Input System
D
  • When domain changes, UserAction needs to be
    changed
  • Source code of FRP to be edited!
  • Hard to compose different domains
  • A robot which receives commands from keyboard
  • All parts of a system must have the same
    UserAction type

26
The New Input System
D
  • Solution
  • Make signals parameterized over the input type
  • type Behavior inp a inp -gt Time -gt a
  • type Event inp a inp -gt Time -gt Maybe a
  • Use type classes to structure multiple input
    types

27
The New Input System
I
  • Type classes
  • class GuiInput gin where
  • lbp Event gin ()
  • mouse Behavior gin Point2
  • class ConInput cin where
  • key Event cin Char
  • Code not using input is polymorphic over input
  • time Behavior inp Time
  • ball Behavior inp Picture
  • ball moveXY (sin time) (cos time) circle
  • Code using input is constrained w/ context
  • kick GuiInput gin gt Behavior gin Real
  • kick 0 until lbp -gt integral 1

28
The New Input System (contd)
D
  • Inputs can be combined
  • Compose input types
  • class (GuiInput in, ConInput in) gt GCInput in
  • instance (GuiInput in, ConInput in) gt GCInput in
  • Have different input types in one system
  • foo Behavior KeyboardInp Real
  • bar Behavior VisionInp Bool
  • Core FRP no longer tided to any particular input
    type
  • User chooses the input module(s) he wants
  • import CoreFRP
  • import Graphics -- Instance of GuiInput and
    ConInput
  • import Vision -- Instance of VisionInput

29
Outline
SPAM
  • Background
  • Design implementation of core FRP
  • Clocked events
  • User implicit vs. explicit
  • Sustainment
  • Modular input
  • Memoization
  • Task monad
  • Future work

30
Memoization
SPAM
I
  • Motivation
  • Behaviors are implemented as functions
  • type Behavior inp a inp -gt Time -gt a
  • Multiple occurrences of a behavior mean
    duplicated computation
  • sqrB b lift2 () b b
  • Even worse for recursive behaviors
  • v v0 k integral v
  • Memoization
  • Needed when a behavior is used more than once
  • sqrB b let b memo b in lift2 () b b
  • Or for recursive behaviors
  • v memo (v0 k integral v)

31
Memoization (contd)
SPAM
I
  • Transparent memoization
  • Implementation detail
  • Shift memo into the definition of combinators
  • Just a hack
  • Sometimes the programmer may need to insert memo
  • Full transparency requires a compiler
  • Side-effect
  • Linear space leak
  • Solution Time bomb!
  • Plant an action in the result stream to flush the
    cache
  • A hack may fail to seal the leak
  • Better let GC flush the cache
  • Requires a hook to the Haskell GC
  • Easier when we compile

32
Outline
  • Background
  • Design implementation of core FRP
  • Clocked events
  • User implicit vs. explicit
  • Sustainment
  • Modular input
  • Memoization
  • Task monad
  • Future work

33
Task
D
  • Task
  • type Task b e (Behavior b, Event e)
  • Why ?
  • Behaviors and events are too low-level.
  • Program is like a network
  • Connections as data dependency
  • s lift2 () a b
  • Sequential temporal composition as switchers
  • a b until (c -gt d)
  • Continuation d must be supplied
  • We want a construct that involves only b and c

34
Task Composition
I
  • Composing tasks
  • Sequential
  • (gtgtgt) Task b x -gt (x -gt Task b y) -gt Task b y
  • (b, e) gtgtgt f
  • (b until e gt (fst . f), e andThen (snd .
    f))
  • andThen Event x -gt (x -gt Event y) -gt Event y
  • Parallel
  • () Task a x -gt Task b x -gt Task (a,b) x

35
Task Is a Monad
D
  • Monad
  • class Monad m where
  • (gtgt) m a -gt (a -gt m b) -gt m b
  • return a -gt m a
  • Task is a monad!
  • Bind (gtgt) is gtgtgt
  • return is instantaneous task
  • return x (undefined, nowE x)

36
Why Monad
D
  • Nicer syntax
  • do x lt- task1
  • task2 x
  • task3
  • compared with
  • task1 gtgtgt
  • (\x -gt task2 x gtgtgt
  • (\_ -gt task3))
  • Easier to understand
  • Libraries on monads ready to use
  • Expandable

37
But Wait!
SPAM
I
  • Task is a monad or really?
  • Implementation of Task
  • (b, e) gtgt f
  • (b until e gt (fst . f), e andThen (snd .
    f))
  • return x (undefined, nowE x)
  • Inspect the first law
  • return x gtgt f
  • (undefined until nowE (fst (f x)), snd (f x))
  • f x (fst (f x), snd (f x))
  • undefined until nowE b b ?
  • Monadic Laws
  • return x gtgt f f x
  • m gtgt return m
  • (associativity)

38
Inside until
SPAM
I

c
tick
k
d
tick
k
buntilc-gtd
tick
k
39
undefined until nowE b vs. b
SPAM
I

undefined
?
tick
nowE
tick
b
tick
undefineduntil nowE b
b
?
?
tick
tick
40
Task Is Not a Monad (Yet)
SPAM
I
  • Law 1 is violated
  • until has a one-step delay
  • b until c -gt d
  • d starts one tick after c occurs
  • Law 2 is violated too
  • Why until introduces delay?
  • Recursive definition
  • a b until (a gt 3) -gt d
  • In a b until c -gt d, where c refers to a,
    the value of a at tick t cannot depend on the
    value of c at tick t

41
Attempt 1 Switch Instantaneously
SPAM
I

b
tick
k
c
tick
k
42
Attempt 2 Start Now, Switch Later
SPAM
I

c
tick
k
?
43
Beyond Simple Tasks
D
  • Need for extending simple tasks
  • Advanced tasks
  • Parallel tasks
  • Interruptible tasks
  • Environment tasks
  • State tasks
  • Message tasks
  • etc

44
Message Tasks
SPAM
D
  • Message Task
  • type MTask m b e (Event m, Behavior b, Event
    e)
  • send m -gt MTask m b ()
  • send m (nowE m, undefined, nowE ())
  • Example
  • do send Phase 1 starts
  • task1
  • send Phase 1 ends
  • send Phase 2 starts
  • task2
  • send Phase 2 ends

45
Mixing until
SPAM
I

f
c
tick
k
mUntil f b (c-gtd)
tick
k
46
Message Tasks -- Implementation
SPAM
I
  • Implementation
  • return e -gt MTask m b e
  • return x (neverE, undefined, nowE x)
  • (gtgt) MTask m b x -gt (x -gt MTask m b y)
  • -gt MTask m b y
  • (m,b,e) gtgt f
  • (mUntil () m (e gt (fst3 . f)),
  • b until (e gt (snd3 . f)),
  • e andThen (thd3 . F)
  • )

47
Structure the Task Hierarchy
I
  • Monolithic type doesnt scale
  • Error-prone
  • Hard to extend
  • Task transformers
  • A type function that maps a Task type to another
    Task type
  • Similar to Monad transformers
  • Idea
  • Factor a complex Task type into orthogonal
    functional units
  • Each unit is a Task transformer
  • Compose functionalities via composing Task
    transformers
  • Pros/Cons of Task transformers
  • Modular
  • Scalable
  • A little overhead

48
Task Transformers
I
  • -- the Generic Task class
  • class GTask t where
  • mkTask Behavior b -gt Event e -gt t b e
  • foreverT Behavior b -gt t b e
  • -- base case
  • instance GTask Task where
  • -- the state task transformer
  • newtype StateT s t b x
  • StateT (s -gt t b (s, x))
  • instance GTask t gt GTask (StateT s t) where

49
Task Transformers (contd)
I
  • -- the environment task transformer
  • newtype EnvT env t b x
  • EnvT (env -gt t b x)
  • instance GTask t gt GTask (EnvT env t) where
  • -- using task transformers
  • type STask s StateT s Task
  • type ESTask env s EnvT env (STask s)

50
Outline
  • Background
  • Design implementation of core FRP
  • Clocked events
  • User implicit vs. explicit
  • Sustainment
  • Modular input
  • Memoization
  • Task monad
  • Future work

51
Future Work
  • Foundation
  • Clock calculus
  • Refined type system
  • Semantics
  • Design
  • Feedback from real world
  • Completeness
  • Implementation
  • Optimization
  • Preprocessing
  • Compilation

52
Future Work
SPAM
  • Optimization
  • Const, Stateless and Stateful
  • type Behavior inp a
  • ConstB a
  • StatelessB (inp -gt Time -gt a)
  • StatefulB (inp -gt Time -gt a)
  • Piecewise-constant behaviors
  • Better memoization
  • Memoization analysis
  • When to memoize, when not to
  • Space leak
  • GC

53
Future Work (contd)
SPAM
  • Better sustainment
  • Problems of runningIn
  • Expensive
  • Doesnt mix w/ recursion
  • Too eager
  • Better implementation for runningIn
  • Garbage collection
  • A construct better than runningIn?

54
Future Work (contd)
SPAM
  • Foundation
  • Clock calculus
  • More refined type system
  • runningIn is a restricted Monad
  • Sub-typing
  • Sustained signals
  • Const/stateless/stateful signals
  • Implementation
  • Preprocessing
  • Compilation

55
Thank You, and Happy Halloween!
Write a Comment
User Comments (0)
About PowerShow.com