Hi, my name is Stian
I'm a frontender
To tackle complexity
That's my job
We are taking lessons from the past
But we are forgetful
Functional programming
Programming with functions
But wait, there's more!
Immutable data
Nothing ever changes
Pure functions
Functions that doesn't do anything
How does this apply to real programs?
Abstractions
User interfaces
Attributes of user interfaces
Global mutable state
Attributes of user interfaces
Asynchronous actions
Attributes of user interfaces
Temporally dependent actions
Attributes of user interfaces
Dependencies between data
What do we need to do in order to use functional programming principles?
- Abstract state mutation
- Declarative dependencies between pieces of state
- Perserve temporal information
Reactive programming
A programming paradigme oriented around data flows and propagation of changes to state.
Data flow programming
Spreadsheets
Values and formulae
How to think in data flow
Reactive datatypes
The primary abstraction
How does reactive programming solve the problem with user interfaces?
Abstract state mutation
The reactive datatypes delegate all state mutation to the underlying execution model
Declarative dependencies between pieces of state
Higher order reactive datatypes
Perserve temporal information
Perserve temporal information
Save the time information connected to a change in state
Continous and discrete
f(t) => v
og [(v, t)]
Functional & Reactive
EventStream & Behavior
Primary abstractions for discrete and continous values
Combinators and functors
Compositional vocabulary from functional programming
We are still mutating the state at the borders of the graph.
What do we achieve?
Functional reasoning despite unfit domain
FRP in practice: Implementations
Implementations of FRP
Haskell and friends
Implementations of FRP
Web and JavaScript
- RxJS
- Elm
- Flapjax
- Bacon.js
FRP in practice: Bacon.js
Sources
fromEventTarget
fromPromise
constant
- and more
Sinks
onValue
Composition
map
filter
reduce
merge
- and many more
Low level
Only the important bits
Example: One-directional binding
Goal: Text in inputfield is replicated in label
var input = Bacon.fromEventTarget(document.querySelector("#text", 'keyup')
var value = input.map(el => el.value)
value.onValue(v => document.querySelector('label').innerHTML = v);
Example: WebSockets and multiple clients.
We are making a simple voting system based on WebSockets.
What we need to do
- Connect and receive data from a WebSocket.
- Count the votes.
- Calculate the percentage each alternative gets.
- Reflect the percentage in the interface.
var socketStream = Bacon.fromEventTarget(socket, "vote");
var totalVoteProperty = function (id) {
return socketStream
.filter(isId(id))
.map(1)
.scan(0, add);
};
var percentage = function (numVotes, total) {
return numVotes
.combine(total, _toPercentage);
};
var sum = socketStream.map(1).scan(0, _add);
["alt1", "alt2", "alt3"].forEach(function (id) {
return percentage(totalVoteProperty(id), sum)
.onValue(v => document.querySelector('#'+id).value = v);
});
How do you spell banana in swedish?
Managing complexity is hard
But functional programming makes it easier
User interfaces are tricky
But reactive programming make them manageable
Combinine functional and reactive programming for a plesant way of managing complexity in user interfaces
Questions, feedback and other things