Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Immutable Truth

The Immutable Truth

The why and how of immutable data structures from the Functional Programming for the web Meetup in London

Avatar for Viktor Charypar

Viktor Charypar

August 18, 2015

Other Decks in Technology

Transcript

  1. why

  2. pure functions • They always do what you expect. Always.

    add(1, 2); // => 3 add(1, 2); // => 3 add(1, 2); // => 3 add(1, 2); // => 4
  3. pure functions • They always do what you expect. Always.

    • Specifically: the same function for the same inputs returns the same value
  4. mutable argument var john = users.get(20); function name(john) {
 return

    john.name;
 } name(john); // => “John” name(john); // => “John” name(john); // => “Paul”
  5. why

  6. how

  7. copy everything var myOwnUsers = users.slice(); • Job done •

    What if we have 1 000 000 users? • And we need a deep copy of each! • SLOW
  8. Tangent: big-O notation • Way to simply describe algorithm complexity


    
 f(x) = O(g(x)) iff |f(x)| ≤ c|g(x)| for x → ∞ • We care about asymptotic growth rate - f grows at most as fast as g • Run time is O(f(n)) - n is the length of input
  9. Examples of big-O • constant – O(1) 
 b =

    a[5]; • linear – O(n)
 x = a.indexOf(“x”); • logarithmic – O(log n)
 x = tree.find(“x”);
  10. copy everything • We want to keep the performance guarantees

    of data structures, e.g. • Vector: constant read and write by index • Map: constant read and write by key • Copy everything on write: linear write
  11. how

  12. Idea 1: structural sharing • Not at all new! First

    in linked lists in 1955 • Clojure, Git, … • Mutation creates a new version which shares some parts with the old version
  13. Example: linked list 1 2 3 4 • {v: 1,

    n: {v: 2, n: {v: 3, n: {…}}}} • [1, [2, [3, [4, null]]]]
  14. Example: tree 1 2 3 4 5 6 1 3

    7 T2 T1 Same thing
  15. Not quite yet • Only works well for lists and

    trees 
 (i.e. directed graphs - nested data) • For simple maps and vectors you still have to copy everything • Viable solution 
 (e.g. React immutability helpers)
  16. how

  17. Idea 2: tries • Again not new. (Fredkin, 1960) •

    Store key - value mapping in a tree • Use parts of the key for branching in a tree
  18. Example: trie c a b t e h n a

    {
 “ten”: “a”,
 “tea”: “b”,
 “the”: “c”
 }
  19. Not quite fast yet • Path copying is O(log L)

    depending on key length • A few keys with common prefixes are a problem • But we’re getting there!
  20. how

  21. Idea 3: hashing • For any value, compute a 32

    bit number • Make sure similar values result in very different numbers
  22. Putting things together • Hash array mapped trie. Pretty new

    (Bagwell, 2000) • Uses binary representation of a hash as a trie key
  23. Pretty fast! • It’s still technically O(log n) • Branching

    factor is 32, so O(log32 n) • For depth 5, you can fit 33 554 432 items • Path copying in < 5 steps ~ constant • It’s a tree, so structural sharing works
  24. Finally var john = users.get(20); function name(john) {
 return john.name;


    } name(john); // => “John” john.set(“name”,“Paul”); // => {name: “Paul”} name(john); // => “John”
  25. So… • Immutability through structural sharing (trees!) • Performance through

    clever data structures • Implementatations for pretty much every language • Natively in Clojure and Scala • Libraries for Haskell, Ruby, JavaScript, …