FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS DAVID WILDE
THE 45TH PRESIDENT BUT FOR HOW LONG?
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS IMMUTABILITY VS MUTABILITY ▸Mutable means ‘capable of changing’ ▸Immutable means ‘cannot change’ ▸Strings are immutable in most programming languages ▸Objects are mutable in JavaScript
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS IMMUTABLE OBJECTS IN THE REAL WORLD ▸ Newspapers ▸ Accountancy Book-keeping ▸ Constitutions/Contracts ▸ Audits ▸ Facts presenting the state of something at a given time
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS IMMUTABILITY IN CODE ▸Javascript numbers are immutable let a = 1 let b = 2 let c = a + b ▸Strings are immutable let a = “foo” let b = “bar” let c = a + b
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS IMMUTABILITY IN CODE ▸Javascript numbers are immutable let a = 1 let b = 2 let c = a + b // a: 1, b: 2, c: 3 ▸Strings are immutable let a = “foo” let b = “bar” let c = a + b
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS IMMUTABILITY IN CODE ▸Javascript numbers are immutable let a = 1 let b = 2 let c = a + b // a: 1, b: 2, c: 3 ▸Strings are immutable let a = “foo” let b = “bar” let c = a + b // a: “foo”, b: “bar”, c: “foobar”
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS IMMUTABILITY IN CODE ▸Some array methods are immutable let a = [ 1, 2 ] let b = [ 3, 4 ] let c = a.concat(b) ▸Others are not let a = [ 1, 2, 5 ] let b = a.push(8)
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS IMMUTABILITY IN CODE ▸Some array methods are immutable let a = [ 1, 2 ] let b = [ 3, 4 ] let c = a.concat(b) // a: [ 1, 2 ] // b: [ 3, 4 ] // c: [ 1, 2, 3, 4 ] ▸Others are not let a = [ 1, 2, 5 ] let b = a.push(8)
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS IMMUTABILITY IN CODE ▸Some array methods are immutable let a = [ 1, 2 ] let b = [ 3, 4 ] let c = a.concat(b) // a: [ 1, 2 ] // b: [ 3, 4 ] // c: [ 1, 2, 3, 4 ] ▸Others are not let a = [ 1, 2, 5 ] let b = a.push(8) // a: [ 1, 2, 5, 8 ]
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS IMMUTABILITY IN CODE ▸Some array methods are immutable let a = [ 1, 2 ] let b = [ 3, 4 ] let c = a.concat(b) // a: [ 1, 2 ] // b: [ 3, 4 ] // c: [ 1, 2, 3, 4 ] ▸Others are not let a = [ 1, 2, 5 ] let b = a.push(8) // a: [ 1, 2, 5, 8 ] // b: 4
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS OBJECT-ORIENTATED PROGRAMMING TENDS TO MUTABILITYclass Kettle { int temperature = 0; int getTemperature() { return this.temperature; } void boil() { this.temperature = 100; } } class Order { int id; drink[] drinks; Order(id) { this.id = id; } addDrink(drink) { this.drinks.push(drink); } process() { } } class Coffee extends Beverage { ...
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS MAKING THIS OPERATION IMMUTABLE var list1 = Immutable.List.of(1, 2) var list2 = list1.push(3, 4, 5) // list1: [ 1, 2 ] // list2: [ 1, 2, 3, 4, 5 ]
FUNCTIONAL PROGRAMMING
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS FUNCTIONS VS CLASSES ▸Functions do specific things ▸Classes are specific things f(x)
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS ARRAY MAP a = [1, 2, 5] function double(value) { return value * 2; } function addOne(value) { return + 1; } b = a.map(double).map(addOne) // b: [3, 5, 11]
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS ARRAY MAP a = [1, 2, 5] const double = (value) => value * 2; const addOne = (value) => value + 1; b = a.map(double).map(addOne) // b: [3, 5, 11]
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS PURE FUNCTIONS var me = { name: “David” }; const hello = () => ( console.log(“Hello, “ + me.name) );
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS PURE FUNCTIONS const hello = (person) => ( “Hello, “ + person.name ); console.log(hello({name: “David”}));
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS PURE FUNCTIONS const myObject = {a: 1, b: 2} const myFunc = (obj) => { obj.a = obj.a * 2 return obj } const newObj = myFunc(myObject) console.log(myObject) // {a: 2, b: 2} console.log(newObj) // {a: 2, b: 2)
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS PURE FUNCTIONS const myImmutable = Immutable.fromJS({a: 1, b: 2}) const myFunc = (obj) => { return myImmutable.set(‘a’, myImmutable.get(‘a’) * 2) } const newObj = myFunc(myObject) console.log(myObject.toJS()) // {a: 1, b: 2} console.log(newObj.toJS()) // {a: 2, b: 2)
PERFORMANCE ENHANCEMENTS USING IMMUTABLE DATA STRUCTURES
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS DRAW DOM BASED ON THE STATE STATE OBJECT SOME INPUT
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS DRAW DOM BASED ON THE STATE STATE OBJECT SOME INPUT CLONED OBJECT COMPARE STATE VS CLONE Same Differ
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS COMPARING TWO OBJECTS IN JAVASCRIPT
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS COMPARING TWO OBJECTS IN JAVASCRIPT function compare2Objects (x, y) { var p; // remember that NaN === NaN returns false // and isNaN(undefined) returns true if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') { return true; } // Compare primitives and functions. // Check if both arguments link to the same object. // Especially useful on the step where we compare prototypes if (x === y) { return true; } // Works in case when functions are created in constructor. // Comparing dates is a common scenario. Another built-ins? // We can even handle functions passed across iframes if ((typeof x === 'function' && typeof y === 'function') || (x instanceof Date && y instanceof Date) || (x instanceof RegExp && y instanceof RegExp) || (x instanceof String && y instanceof String) || (x instanceof Number && y instanceof Number)) { return x.toString() === y.toString(); } // At last checking prototypes as good as we can if (!(x instanceof Object && y instanceof Object)) { return false; } if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) { return false; } if (x.constructor !== y.constructor) { return false; } if (x.prototype !== y.prototype) { return false; } // Check for infinitive linking loops if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) { return false; } // Quick checking of one object being a subset of another. // todo: cache the structure of arguments[0] for performance for (p in y) { if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { return false; } else if (typeof y[p] !== typeof x[p]) { return false; } } for (p in x) { if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { return false; } else if (typeof y[p] !== typeof x[p]) { return false; } switch (typeof (x[p])) { case 'object': case 'function': leftChain.push(x); rightChain.push(y); if (!compare2Objects (x[p], y[p])) { return false; } leftChain.pop(); rightChain.pop(); break; default: if (x[p] !== y[p]) { return false; } break; } }
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS COMPARING TWO OBJECTS IN JAVASCRIPT
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS PARTICULAR PERFORMANCE IMPROVEMENTS ARE AVAILABLE DRAW DOM BASED ON THE STATE STATE OBJECT SOME INPUT STORE OLD REF COMPARE STATE REF VS OLD REF Same Differ
STRUCTURAL SHARING
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS PERSISTENT DATA STRUCTURES 1 List.of([ 1, 2, 3, 5, 8 ]).push(13) 2 3 50x0012 8
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS PERSISTENT DATA STRUCTURES 1 2 3 50x0012 1 2 3 50x0042 8 8 13 List.of([ 1, 2, 3, 5, 8 ]).push(13)
TRIE
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS STRUCTURAL SHARING 2 3 5 0x0012 1 8 List.of([ 1, 2, 3, 5, 8 ]).push(13)
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS STRUCTURAL SHARING 2 3 5 0x0012 1 8 1 8 13 0x0042 List.of([ 1, 2, 3, 5, 8 ]).push(13)
CONCLUSION
WORKSHOP https://github.com/davidwilde/poop-sweeper
FUNCTIONAL PROGRAMMING WITH IMMUTABLE.JS IMMUTABLE.JS var map = Immutable.Map({ a: 1, b: 2, c: 3 }) map .set('b', 50) .get('b') // 50 var list = Immutable.List.of(1, 2) list .push(3, 4, 5) .unshift(0) .concat(list2, list3) .get(0) .size var nested = Immutable.fromJS({ user: { profile: { name: 'John' } } }) nested .mergeDeep({ user: { profile: { age: 90 } } }) .setIn([ 'user', 'profile', 'name' ], 'Jack') .updateIn([ 'user', 'profile', 'name' ], (s) => s.toUpperCase()) .getIn(['user', 'profile', 'name']) // 'JACK'

Functional programming with Immutable .JS

  • 1.
  • 2.
  • 4.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS IMMUTABILITY VS MUTABILITY ▸Mutable means ‘capable of changing’ ▸Immutable means ‘cannot change’ ▸Strings are immutable in most programming languages ▸Objects are mutable in JavaScript
  • 5.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS IMMUTABLE OBJECTS IN THE REAL WORLD ▸ Newspapers ▸ Accountancy Book-keeping ▸ Constitutions/Contracts ▸ Audits ▸ Facts presenting the state of something at a given time
  • 6.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS IMMUTABILITY IN CODE ▸Javascript numbers are immutable let a = 1 let b = 2 let c = a + b ▸Strings are immutable let a = “foo” let b = “bar” let c = a + b
  • 7.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS IMMUTABILITY IN CODE ▸Javascript numbers are immutable let a = 1 let b = 2 let c = a + b // a: 1, b: 2, c: 3 ▸Strings are immutable let a = “foo” let b = “bar” let c = a + b
  • 8.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS IMMUTABILITY IN CODE ▸Javascript numbers are immutable let a = 1 let b = 2 let c = a + b // a: 1, b: 2, c: 3 ▸Strings are immutable let a = “foo” let b = “bar” let c = a + b // a: “foo”, b: “bar”, c: “foobar”
  • 9.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS IMMUTABILITY IN CODE ▸Some array methods are immutable let a = [ 1, 2 ] let b = [ 3, 4 ] let c = a.concat(b) ▸Others are not let a = [ 1, 2, 5 ] let b = a.push(8)
  • 10.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS IMMUTABILITY IN CODE ▸Some array methods are immutable let a = [ 1, 2 ] let b = [ 3, 4 ] let c = a.concat(b) // a: [ 1, 2 ] // b: [ 3, 4 ] // c: [ 1, 2, 3, 4 ] ▸Others are not let a = [ 1, 2, 5 ] let b = a.push(8)
  • 11.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS IMMUTABILITY IN CODE ▸Some array methods are immutable let a = [ 1, 2 ] let b = [ 3, 4 ] let c = a.concat(b) // a: [ 1, 2 ] // b: [ 3, 4 ] // c: [ 1, 2, 3, 4 ] ▸Others are not let a = [ 1, 2, 5 ] let b = a.push(8) // a: [ 1, 2, 5, 8 ]
  • 12.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS IMMUTABILITY IN CODE ▸Some array methods are immutable let a = [ 1, 2 ] let b = [ 3, 4 ] let c = a.concat(b) // a: [ 1, 2 ] // b: [ 3, 4 ] // c: [ 1, 2, 3, 4 ] ▸Others are not let a = [ 1, 2, 5 ] let b = a.push(8) // a: [ 1, 2, 5, 8 ] // b: 4
  • 13.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS OBJECT-ORIENTATED PROGRAMMING TENDS TO MUTABILITYclass Kettle { int temperature = 0; int getTemperature() { return this.temperature; } void boil() { this.temperature = 100; } } class Order { int id; drink[] drinks; Order(id) { this.id = id; } addDrink(drink) { this.drinks.push(drink); } process() { } } class Coffee extends Beverage { ...
  • 14.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS MAKING THIS OPERATION IMMUTABLE var list1 = Immutable.List.of(1, 2) var list2 = list1.push(3, 4, 5) // list1: [ 1, 2 ] // list2: [ 1, 2, 3, 4, 5 ]
  • 15.
  • 16.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS FUNCTIONS VS CLASSES ▸Functions do specific things ▸Classes are specific things f(x)
  • 17.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS ARRAY MAP a = [1, 2, 5] function double(value) { return value * 2; } function addOne(value) { return + 1; } b = a.map(double).map(addOne) // b: [3, 5, 11]
  • 18.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS ARRAY MAP a = [1, 2, 5] const double = (value) => value * 2; const addOne = (value) => value + 1; b = a.map(double).map(addOne) // b: [3, 5, 11]
  • 19.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS PURE FUNCTIONS var me = { name: “David” }; const hello = () => ( console.log(“Hello, “ + me.name) );
  • 20.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS PURE FUNCTIONS const hello = (person) => ( “Hello, “ + person.name ); console.log(hello({name: “David”}));
  • 21.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS PURE FUNCTIONS const myObject = {a: 1, b: 2} const myFunc = (obj) => { obj.a = obj.a * 2 return obj } const newObj = myFunc(myObject) console.log(myObject) // {a: 2, b: 2} console.log(newObj) // {a: 2, b: 2)
  • 22.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS PURE FUNCTIONS const myImmutable = Immutable.fromJS({a: 1, b: 2}) const myFunc = (obj) => { return myImmutable.set(‘a’, myImmutable.get(‘a’) * 2) } const newObj = myFunc(myObject) console.log(myObject.toJS()) // {a: 1, b: 2} console.log(newObj.toJS()) // {a: 2, b: 2)
  • 23.
  • 24.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS DRAW DOM BASED ON THE STATE STATE OBJECT SOME INPUT
  • 25.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS DRAW DOM BASED ON THE STATE STATE OBJECT SOME INPUT CLONED OBJECT COMPARE STATE VS CLONE Same Differ
  • 26.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS COMPARING TWO OBJECTS IN JAVASCRIPT
  • 27.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS COMPARING TWO OBJECTS IN JAVASCRIPT function compare2Objects (x, y) { var p; // remember that NaN === NaN returns false // and isNaN(undefined) returns true if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') { return true; } // Compare primitives and functions. // Check if both arguments link to the same object. // Especially useful on the step where we compare prototypes if (x === y) { return true; } // Works in case when functions are created in constructor. // Comparing dates is a common scenario. Another built-ins? // We can even handle functions passed across iframes if ((typeof x === 'function' && typeof y === 'function') || (x instanceof Date && y instanceof Date) || (x instanceof RegExp && y instanceof RegExp) || (x instanceof String && y instanceof String) || (x instanceof Number && y instanceof Number)) { return x.toString() === y.toString(); } // At last checking prototypes as good as we can if (!(x instanceof Object && y instanceof Object)) { return false; } if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) { return false; } if (x.constructor !== y.constructor) { return false; } if (x.prototype !== y.prototype) { return false; } // Check for infinitive linking loops if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) { return false; } // Quick checking of one object being a subset of another. // todo: cache the structure of arguments[0] for performance for (p in y) { if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { return false; } else if (typeof y[p] !== typeof x[p]) { return false; } } for (p in x) { if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { return false; } else if (typeof y[p] !== typeof x[p]) { return false; } switch (typeof (x[p])) { case 'object': case 'function': leftChain.push(x); rightChain.push(y); if (!compare2Objects (x[p], y[p])) { return false; } leftChain.pop(); rightChain.pop(); break; default: if (x[p] !== y[p]) { return false; } break; } }
  • 28.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS COMPARING TWO OBJECTS IN JAVASCRIPT
  • 29.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS PARTICULAR PERFORMANCE IMPROVEMENTS ARE AVAILABLE DRAW DOM BASED ON THE STATE STATE OBJECT SOME INPUT STORE OLD REF COMPARE STATE REF VS OLD REF Same Differ
  • 30.
  • 31.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS PERSISTENT DATA STRUCTURES 1 List.of([ 1, 2, 3, 5, 8 ]).push(13) 2 3 50x0012 8
  • 32.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS PERSISTENT DATA STRUCTURES 1 2 3 50x0012 1 2 3 50x0042 8 8 13 List.of([ 1, 2, 3, 5, 8 ]).push(13)
  • 33.
  • 34.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS STRUCTURAL SHARING 2 3 5 0x0012 1 8 List.of([ 1, 2, 3, 5, 8 ]).push(13)
  • 35.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS STRUCTURAL SHARING 2 3 5 0x0012 1 8 1 8 13 0x0042 List.of([ 1, 2, 3, 5, 8 ]).push(13)
  • 36.
  • 37.
  • 38.
    FUNCTIONAL PROGRAMMING WITHIMMUTABLE.JS IMMUTABLE.JS var map = Immutable.Map({ a: 1, b: 2, c: 3 }) map .set('b', 50) .get('b') // 50 var list = Immutable.List.of(1, 2) list .push(3, 4, 5) .unshift(0) .concat(list2, list3) .get(0) .size var nested = Immutable.fromJS({ user: { profile: { name: 'John' } } }) nested .mergeDeep({ user: { profile: { age: 90 } } }) .setIn([ 'user', 'profile', 'name' ], 'Jack') .updateIn([ 'user', 'profile', 'name' ], (s) => s.toUpperCase()) .getIn(['user', 'profile', 'name']) // 'JACK'

Editor's Notes

  • #2 Thank Steve + Yolk Introduce myself. Graduated in 2002, been developing for 15 years. Today I will give an overview about what immutable data structures are what functional programming is and how immutable.js can help you to write pure functions in javascript efficiently
  • #3 Some people will be thinking less than 4 years, some will think that he will see out the term. There may be some that think 8 years. Forever… the next one will be the 46th Does anyone think more than 8 years?
  • #5 I wanted to think about what immutable objects there are in the real world. Ask the audience for their ideas
  • #6 Prohibition is 18th Amendment, 21st Amendment repeal If we are concerned with truthfulness, then it is a good idea to use an immutable object
  • #9 This is just very normal to us
  • #13 This shows an inconsistency, which could cause bugs At the point in time that we are performing the push operation we don’t know what a actually is. Something else could have messed with it
  • #14 Objects are usually made up of identity, internal state and behaviour The problem is that in object-orientation you usually don't create data-structures. You encapsulate and hide data instead. Data-access is often even viewed as bad We often think about objects in the present
  • #15 All well and good but what’s so great about this…
  • #16 Something that I’m new to. I’ve had my brain wired for Object-orientated programming for 15 years. It’s a bit hipster - Lisp was invented in 1958 Until recently has been seen as something for mathematicians - not part of the enterprise world. Parts can get really hard - e.g. Monads This is changing because: Current popularity due to massively parallel systems. Fixing problems with state management Due to Javascript not being purely functional - it is a great introduction to FP. Some lousy things go away like ‘this’
  • #17 Functional programming at its core is is thinking of functions as king rather than objects. Data is transformed through functions which can be composed together to make an application With functional programming, for a given input it will return a consistent output Truth
  • #18 Higher-order function Snazzy ES-6 notation
  • #20 The console is not part of the function
  • #22 When dealing with objects and arrays there is a danger of unintended impurity
  • #24 Immutablity is not a magic bullet, but used well, they can be used to improve the performance of applications
  • #25 Maybe key presses don’t change the DOM. Maybe this is a webmail client and it is polling the network
  • #26 Copying is simply a matter of creating a new reference to the existing piece of data
  • #29 With immutable objects you only create a new object if the object has changed. This is comparing two references and couldn’t be much cheaper and easier.
  • #30 Copying is simply a matter of creating a new reference to the existing piece of data However this can be further optimised thanks to a feature of immutable.js…
  • #31 People can’t let go of the idea that you are creating masses of data
  • #33 You can see from this how an undo feature is really easy. We just somehow go back to the memory address 0x0012
  • #37 Immutable objects can be a beneficial tool in your programming arsenal Reach for them when you care about the truthfulness of state