Immutability
How NOT to worry about side effects
State
vs.
Pure Functions
State
-
Result depends on it
function Adder(first, second) {
this.first = first;
this.second = second;
this.sum = function () {
return this.first + this.second;
}
}
var adder = new Adder(2, 3);
adder.sum();
State
-
Introduces an additional parameter: TIME
function Adder(first, second) {
...
this.setFirst = function(first) {
this.first = first;
}
this.setSecond = function(second) {
this.second = second;
}
}
var adder = new Adder(2, 3);
... //black hole :P
adder.sum(); // =?Those who don't play nice
function badGuy(param) {
param.first = 10;
param.second = -1;
}
var adder = new Adder(2, 3);
badGuy(adder) //i don't know what bad guy does
adder.sum(); // =5, right? :P-
don't mutate the parameters inside a function (seriously, don't!)
Pure functions
function Adder() {
this.sum = function(first, second) {
return first + second;
}
}
var adder = new Adder();
adder.sum(2, 3); // =5, always!-
no state
-
depend only on parameters
-
play very nice with immutable objects
Case Study
------------- ---------------
| | items | |
| Loader | -------> | Presenter |
| | | |
------------- ----------------
can select items in the presenter
function markSelected(item) {
item.selected = true
}------------- ---------------
| | items | |
| Loader | -------> | Presenter |
| | | |
------------- ---------------
\ ---------------
\ items | |
-------> |2nd Presenter|
| |
----------------
can select items in the second presenter
item.selected = true ???------------- ---------------
| | items | |
| Loader | -------> | Presenter |
| | | |
------------- ---------------
\ ---------------
\ items | |
-------> |2nd Presenter|
| |
----------------
reload data from the server
fetchData(...)
.then(loadedData => this.myData = loadedData)that easy?
-
the presenters have just lost the selected state
-
start doing all sort of complex logic
fetchData(...)
.then(loadedData => {
this.myData.length = 0;
for (let item of loadedData) {
this.myData.push(item);
}
})the presenters are f**ked again...
fetchData(...)
.then(loadedData => {
this.oldData = copy(this.myData);
this.myData.length = 0;
for (let item of loadedData) {
if (isSelectedByFirstPresenter(item, this.oldData)) {
item.selected = true;
}
this.myData.push(item);
}
})
function isSelectedByFirstPresenter(item, oldData) {
//indexOf won't work because it's a new object
return this.oldData.any((oldItem) => equals(oldItem, item) && oldItem.selected);
}what is selected and why do i know about it?
In short
- exposed to unwanted changes
-
no real owner of the data
-
have to take care/account for others
-
complex equality checks for complex objects
There is no silver bullet
There is no silver bullet
X
Immutability
Immutable objects
- can't change an object
- can only create a new, changed object
- data ownership
let state = {
who: 'Ana',
has: 'apples',
count: 5
}
state.count = 6;
expect(state.count).to.equal(6);let state = {
who: 'Ana',
has: 'apples',
count: 5
}
let nextState = state.set('count', 6)
expect(nextState.count).to.equal(6);
expect(state.count).to.equal(5);No things in life are free
- loader and presenter can't share the same list if they want to change it
- each handles it's own s***t:
- loader loads data and gives it to the presenters
- they dirty it up with whatever they want
No things in life are free
- memory consumption
- garbage collection usage
really? :P
- data event subscription
- complex bookkeeping
- sync issues
- copy = deep cloning
- unidirectional data flow
- react to data
- easily detect data changes (equality check)
- copy = add another reference => O(1)
- anything is undo-able
- lazy operations - 100% the data will not change
Before & After
Memory

let brown = Range(0, 9);
let blue = brown.set(5, 'beef');Examples
Lazy Sequence
Tips
- use immutable objects (duh :P)
- API, module interfaces, communicating with the view
- don't mix mutable and immutable data in the same place
- familiarise with FP (it's here to stay)
Up next:




Q & A
Thanks!
Resources
- https://facebook.github.io/immutable-js/
- http://hypirion.com/musings/understanding-persistent-vector-pt-1
- https://idea.popcount.org/2012-07-25-introduction-to-hamt/
- http://jlongster.com/Using-Immutable-Data-Structures-in-JavaScript
state
By Horia Radu
state
- 292