240 likes | 390 Views
Elm: Making t he W eb Functional. with Functional Reactive Programming Evan Czaplicki. Reactivity. There are many kinds of interaction: User input: mouse, keyboard, touch, etc. Sensors: accelerometer, GPS File I/O Network communications: HTTP Many interesting problems are reactive.
E N D
Elm: Making the Web Functional with Functional Reactive Programming Evan Czaplicki
Reactivity • There are many kinds of interaction: • User input: mouse, keyboard, touch, etc. • Sensors: accelerometer, GPS • File I/O • Network communications: HTTP • Many interesting problems are reactive. • Robotics • Music Synthesis • Video Games • Graphical User Interfaces
Graphical User Interfaces Display Compute React
GUIs in OCaml Display Compute Worry about overwriting pixels. Object types need to match. Great! React Inherently stateful. Global state is required. Polling: • The event loop is constantly asking “any changes, any changes, …” • Wastes energy and processor time.
GUIs on the Web Display Compute HTML , CSS Originally only for text! JavaScript Not great! React JavaScript Events and listeners. Browser Incompatibility • The same code does different things in different browsers!
GUIs on the Web • Besides the conceptual and practical problems, web programming has another disadvantage. Kübler-Ross model
GUIs in Elm Display Compute Compiler handles refreshing screen. Uniform types for graphical elements. Purely functional language. React Does not rely on stateful abstractions! Event-driven updates: • Do not poll for changes! • Updates are pushed to the program as necessary. • Uncommon in FRP, but JavaScript actually makes this easier.
Functional Displays Adding the Element and Form types.
“Pure” Functions • Same input results in the same output: square x = x * x • A great property for writing modular and maintainable code. • A type is a contract: square :: Int → Int • How can we make squareimpure?
Are pure functions worth it? • A program can be pure if: • No memory access. • No side-effects. • No interaction. • All values must be immutable. • Values cannot change after creation. • Can a pure language be useful? • How do you even talk about user input? • How do you save information?
So are pure functions worth it? Not really.
Introducing Interaction • Just do it: the OCaml method. • Simple but functions may not be pure. • A pure language is a great opportunity to rethink interaction. • Goal: Interaction is possible, but a type is still a contract. • What would functional interaction look like? • How can mutable values be introduced safely?
Events type id type ‘a event valkey_pressed : char event valbutton_down : (int * int) event valbutton_up : (int * int) event valmouse_motion : (int * int) event val clock : unit event valadd_listener : ‘a event -> (‘a -> unit) -> id
Functional Reactive Programming • Recast mutable values as time-varying values. • Time-varying values are called “signals”. Mouse.position :: Signal (Int,Int) • A signal is like a stream of events. • Displaying the mouse position: an example.
Transforming Signals lift :: (a → b) → Signal a → Signal b • An animation has type (Signal Element). • It is an Element that changes over time!
Transforming Signals liftN :: (a1 → … → an → a) → Signal a1 → … → Signal an → Signal a • How do we count clicks? • What if a signal depends on the past?
Stateful Signals foldp :: (a → b → b) → b → Signal a → Signal b
Reactive Examples Creating a GUI with Elm
Concurrent GUIs • Graphical user interfaces are naturally concurrent. • Independent elements can be updated independently. • Long computations should not block unrelated events. • How can concurrency be introduced without: • causing event-ordering problems? • making the language more error-prone with low-level abstractions? • corrupting the “purity” of a functional language? • My thesis combines FRP and concurrency. • Another approach: Concurrent ML
Synchronization • In most cases, the order of input events must be maintained in a GUI. • Concurrency makes it possible for events to get out of order. • This problem is addressed with synchronization.
Switching Signals • What if a stateful signal (created with foldp) is created a minute after the program starts? • Does it depend on all past events? • What if a stateful signal is removed from the program, but may be put back in later? • Does it continue to get updated? • Does it stop getting updates? • These questions do not appear to have a clear answer. • Arrowized FRP solves the problem by reformulating FRP.
More Information • “Related Work” and “References” in my thesis. • Functional Reactive Programming for Haskell • The very well-written original paper on FRP (1997). • Papers on Concurrent ML. • Try out Elm at elm-lang.org.
Questions Possibly answers too.