**Controlling**

Time and Space

Time and Space

**Evan Czaplicki**

**@czaplic / elm-lang.org / Prezi**

**Understanding the many formulations of**

Functional Reactive Programming

Functional Reactive Programming

Core Design

Signals are connected to the world

Signals are infinite

Signal graphs are static

Synchronous by default

Core Design

Signals are connected to the world

Signals are infinite

Signal graphs are static

Synchronous by default

Core Design

Signals are connected to the world

Signals are infinite

Signal graphs are static

Synchronous by default

Pursuing Reconfigurable Graphs

Arrowized FRP

Asynchronous

Data Flow

Higher-order FRP

Mouse

.

position

:

Signal

(

Int

,

Int

)

Inputs

Transformations

State

Keyboard

.

lastPressed

:

Signal

Int

foldp

: (

a

->

b

->

b

) ->

b

->

Signal

a

->

Signal

b

"fold from the past"

foldp

(\

key

count

->

count

+

1

)

0

Keyboard

.

lastPressed

1

2

3

4

5

6

7

8

9

10

11

map

: (

a

->

b

) ->

Signal

a

->

Signal

b

map

isConsonant

Keyboard

.

lastPressed

First-order FRP

What happens if

signal graphs can be reconfigured?

Core Design

T

F

T

T

F

F

T

T

T

F

T

map2

: (

a

->

b

->

c

) ->

Signal

a

->

Signal

b

->

Signal

c

...

merge

:

Signal

a

->

Signal

a

->

Signal

a

Merge

Infinite Signals

Finite Event Streams

Neither!

Static Graphs

Dynamic Graphs

Does the code come out nice?

**Categorize**

Synchronous by default?

Allows reconfiguration of graph?

Allows asynchrony?

What properties do I need for my application?

**Evaluate**

pure

: (

a

->

b

) ->

Automaton

a

b

state

:

s

-> (

a

->

s

->

s

) ->

Automaton

a s

(

>>>

) :

Automaton

a

b

->

Automaton

b c

->

Automaton

a c

join

:

Signal

(

Signal

a

) ->

Signal

a

flatten

:

Signal

(

Signal

a

) ->

Signal

a

clickCount

:

Signal Int

clickCount

=

count Mouse.clicks

clicksOrZero

:

Bool

->

Signal

Int

clicksOrZero

clicks =

if

clicks

then

count Mouse.clicks

else

constant

0

Example

Solution

Restrict the definition of

join

with fancier types.

Only switch to signals that have "safe" amounts of history.

Higher-order functional reactive programming in bounded space

by Neelakantan R. Krishnaswami, Nick Benton, and Jan Hoffmann

...

Problem

Creating a new signal may need infinite look back!

Memory growth is linear with time!

Reactive Extensions

ReactiveCocoa

Bacon.js

Haskell:

Yampa

,

Netwire

Event-Driven FRP

Real-Time FRP

Elm

Signal Graphs

clickCount

:

Signal Int

clickCount

=

count Mouse.clicks

clicksOrZero

:

Bool

->

Signal

Int

clicksOrZero

clicks =

if

clicks

then

count Mouse.clicks

else

constant

0

{

Dynamic

Collections

count

count

count

count

count

count

count

count

Elm:

Automaton

count

:

Automaton

a

Int

count

= state

0

(\

a total

->

total

+

1

)

plus1

:

Automaton Int Int

plus1

= pure (\

n

->

n

+

1

)

plus2

:

Automaton Int Int

plus2

= plus1 >>> plus1

Basic API

Examples

Benefits in Elm

Architecture

Hot-swapping

Time-travel debugging

Efficiency

Synchronous by default

Signal graphs are static

Signals are infinite

Signals are connected to the world

https://github.com/evancz/elm-architecture-tutorial/

http://elm-lang.org/edit/examples/Intermediate/Mario.elm

http://debug.elm-lang.org/

"How it works in Elm"

Can I talk about inputs?

**Understand**

http://elm-lang.org/

What is debugging like?

http://elm-lang.org/papers/concurrent-frp.pdf