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

Building Functional Islands

Building Functional Islands

A talk about functional programming at the April 2016 Front End London http://frontendlondon.co.uk

Bca1b99f923e255051cbd09bae751e7a?s=128

Mark Jones

April 28, 2016
Tweet

Transcript

  1. Building Functional Islands

  2. Audience Participation

  3. What is Functional Programming?

  4. Statements const nums = [1, 2, 3]; const doubled =

    []; for (let i = 0; i < nums.length; i++) { doubled.push(nums[i] * 2); }
  5. Statements const nums = [1, 2, 3]; const doubled =

    []; for (let i = 0; i < nums.length; i++) { doubled.push(nums[i] * 2); }
  6. Statements const nums = [1, 2, 3]; const doubled =

    []; for (let i = 0; i < nums.length; i++) { doubled.push(nums[i] * 2); }
  7. Statements const nums = [1, 2, 3]; const doubled =

    []; for (let i = 0; i < nums.length; i++) { doubled.push(nums[i] * 2); }
  8. function double(x) { return x * 2; } map([1, 2,

    3], double); Expressions
  9. function double(x) { return x * 2; } map([1, 2,

    3], double); // [(1 * 2), (2 * 2), (3 * 2)] Expressions
  10. function double(x) { return x * 2; } map([1, 2,

    3], double); // [(1 * 2), (2 * 2), (3 * 2)] // [2, 4, 6] Expressions
  11. Why Functional Programming?

  12. Functions Island Building Block #1

  13. First-Class Functions function onClick() { // I'm a first-class function

    } document.body.addEventListener('click', onClick);
  14. function onClick() { // I get called by a higher-order

    function } document.body.addEventListener('click', onClick); Higher-Order Functions
  15. Higher-Order Functions function logify(fn) { return (...args) => { console.log(args);

    return fn(...args); }; } const logifyAdd = logify(add); function add(x, y) { return x + y; }
  16. Higher-Order Functions function logify(fn) { return (...args) => { console.log(args);

    return fn(...args); }; } const logifyAdd = logify(add); function add(x, y) { return x + y; }
  17. Higher-Order Functions function logify(fn) { return (...args) => { console.log(args);

    return fn(...args); }; } const logifyAdd = logify(add); function add(x, y) { return x + y; }
  18. Higher-Order Functions const logifyAdd = logify(add); logifyAdd(1, 2); // [1,

    2] // 3
  19. Higher-Order Functions The Benefits

  20. Pure Functions function add(x, y) { // I'm a pure

    function return x + y; }
  21. Pure Functions add(1, 2) + add(3, 4);

  22. Pure Functions add(1, 2) + add(3, 4); // 3 +

    add(3, 4);
  23. Pure Functions add(1, 2) + add(3, 4); // 3 +

    add(3, 4); // 3 + 7;
  24. Pure Functions add(1, 2) + add(3, 4); // 3 +

    add(3, 4); // 3 + 7; // 10;
  25. function addAndSomethingElse(x, y) { // I'm an impure function doSomethingElse();

    return x + y; } Pure Functions
  26. Pure Functions addAndSomethingElse(1, 2) // ???

  27. Pure Functions The Benefits

  28. Pure Functions The Reality

  29. Immutability Island Building Block #2

  30. Immutable values const nums = [1, 2, 3]; const person

    = { name: 'mark', age: 29 }; nums[0] = 2; // [2, 2, 3] person.age = 27; // { name: 'mark', age: 27 }
  31. Immutable values const nums = [1, 2, 3]; const person

    = { name: 'mark', age: 29 }; nums[0] = 2; // [2, 2, 3] person.age = 27; // { name: 'mark', age: 27 }
  32. Immutable values const nums = [1, 2, 3]; const person

    = { name: 'mark', age: 29 }; nums[0] = 2; // [2, 2, 3] person.age = 27; // { name: 'mark', age: 27 }
  33. Immutable values const nums = [1, 2, 3]; const person

    = { name: 'mark', age: 29 }; nums[0] = 2; // [2, 2, 3] person.age = 27; // { name: 'mark', age: 27 }
  34. Object.freeze const nums = Object.freeze([1, 2, 3]); const person =

    Object.freeze({ name: 'mark', age: 29 }); nums[0] = 2; // [1, 2, 3] person.age = 27; // { name: 'mark', age: 29 }
  35. Object.freeze const nums = Object.freeze([1, 2, 3]); const person =

    Object.freeze({ name: 'mark', age: 29 }); nums[0] = 2; // [1, 2, 3] person.age = 27; // { name: 'mark', age: 29 }
  36. Object.freeze const nums = Object.freeze([1, 2, 3]); const person =

    Object.freeze({ name: 'mark', age: 29 }); nums[0] = 2; // [1, 2, 3] person.age = 27; // { name: 'mark', age: 29 }
  37. Object.freeze const employee = Object.freeze({ department: 'Eng', profile: { name:

    'mark', age: 29 } }); employee.profile.age = 27; // {...{ name: 'mark', age: 27 } }
  38. Object.freeze const employee = Object.freeze({ department: 'Eng', profile: { name:

    'mark', age: 29 } }); employee.profile.age = 27; // {...{ name: 'mark', age: 27 } }
  39. Object.freeze const employee = Object.freeze({ department: 'Eng', profile: { name:

    'mark', age: 29 } }); employee.profile.age = 27; // {...{ name: 'mark', age: 27 } }
  40. deepFreeze const employee = deepFreeze({ department: 'Eng', profile: { name:

    'mark', age: 29 } }); employee.profile.age = 27; // {...{ name: 'mark', age: 29 } }
  41. Immutability The Benefits

  42. Immutability The Reality

  43. Currying Island Building Block #3

  44. Currying const add = curry((x, y) => { return x

    + y; }); const succ = add(1); succ(1); // 2
  45. Currying const add = curry((x, y) => { return x

    + y; }); const succ = add(1); succ(1); // 2
  46. Currying const add = curry((x, y) => { return x

    + y; }); const succ = add(1); succ(1); // 2
  47. Currying const devs = [ { firstName: 'mark' }, {

    firstName: 'sally' } ]; const firstNames = map(devs, (dev) => { return dev.firstName; });
  48. Currying const devs = [ { firstName: 'mark' }, {

    firstName: 'sally' } ]; const firstNames = map(devs, (dev) => { return dev.firstName; });
  49. Currying const devs = [ { firstName: 'mark' }, {

    firstName: 'sally' } ]; const firstNames = map(devs, (dev) => { return dev.firstName; });
  50. Currying const devs = [ { firstName: 'mark' }, {

    firstName: 'sally' } ]; const getFirstNames = map(prop('firstName')); const firstNames = getFirstNames(devs);
  51. Currying const devs = [ { firstName: 'mark' }, {

    firstName: 'sally' } ]; const getFirstNames = map(prop('firstName')); const firstNames = getFirstNames(devs);
  52. Currying const devs = [ { firstName: 'mark' }, {

    firstName: 'sally' } ]; const getFirstNames = map(prop('firstName')); const firstNames = getFirstNames(devs);
  53. Currying const devs = [ { firstName: 'mark' }, {

    firstName: 'sally' } ]; const getFirstNames = map(prop('firstName')); const firstNames = getFirstNames(devs);
  54. Currying The Benefits

  55. Currying The Reality

  56. Composition Island Building Block #4

  57. Composition const value = 1; const gRes = g(value); const

    fgRes = f(gRes);
  58. Composition const value = 1; const gRes = g(value); const

    fgRes = f(gRes);
  59. Composition const value = 1; const gRes = g(value); const

    fgRes = f(gRes);
  60. Composition const value = 1; const gRes = g(value); const

    fgRes = f(gRes);
  61. Composition function fg(x) { return f(g(x)); } fg(1);

  62. Composition const fg = compose(f, g); fg(1);

  63. Composition function getFilmIdsFromResponse(resp) { return getIds(getFilms(JSON.parse(resp))); } getFilmIdsFromResponse('{ "films": [{

    id: 1 }, ...], "actors": [...] }');
  64. Composition function getFilmIdsFromResponse(resp) { return getIds(getFilms(JSON.parse(resp))); } getFilmIdsFromResponse('{ "films": [{

    id: 1 }, ...], "actors": [...] }');
  65. Composition function getFilmIdsFromResponse(resp) { return getIds(getFilms(JSON.parse(resp))); } getFilmIdsFromResponse('{ "films": [{

    id: 1 }, ...], "actors": [...] }');
  66. Composition function getFilmIdsFromResponse(resp) { return getIds(getFilms(JSON.parse(resp))); } getFilmIdsFromResponse('{ "films": [{

    id: 1 }, ...], "actors": [...] }');
  67. Composition function getFilmIdsFromResponse(resp) { return getIds(getFilms(JSON.parse(resp))); } getFilmIdsFromResponse('{ "films": [{

    id: 1 }, ...], "actors": [...] }');
  68. Composition const getIds = map(prop('id')); const getFilmIdsFromResponse = compose(getIds, prop('films'),

    JSON.parse); getFilmIdsFromResponse('{ "films": [...], "actors": [...] }');
  69. Composition const getIds = map(prop('id')); const getFilmIdsFromResponse = compose(getIds, prop('films'),

    JSON.parse); getFilmIdsFromResponse('{ "films": [...], "actors": [...] }');
  70. Composition const getIds = map(prop('id')); const getFilmIdsFromResponse = compose(getIds, prop('films'),

    JSON.parse); getFilmIdsFromResponse('{ "films": [...], "actors": [...] }');
  71. Composition const getIds = map(prop('id')); const getFilmIdsFromResponse = compose(getIds, prop('films'),

    JSON.parse); getFilmIdsFromResponse('{ "films": [...], "actors": [...] }');
  72. Composition const getIds = map(prop('id')); const getFilmIdsFromResponse = compose(getIds, prop('films'),

    JSON.parse); getFilmIdsFromResponse('{ "films": [...], "actors": [...] }');
  73. Composition The Benefits

  74. Composition The Reality

  75. I’m confused. What’s a functional island again?

  76. Further reading / watch list (free) https://drboolean.gitbooks.io/mostly-adequate-guide/content/ Professor Frisby's Mostly

    Adequate Guide to Functional Programming http://ramdajs.com/ A practical functional library for Javascript programmers https://github.com/lodash/lodash/wiki/FP-Guide lodash/fp guide https://www.youtube.com/watch?v=m3svKOdZijA Hey Underscore, You're Doing It Wrong! https://github.com/substack/deep-freeze deepFreeze
  77. Further reading / watch list (paid) https://frontendmasters.com/courses/functional-js-lite/ Functional Lite JavaScript

    https://frontendmasters.com/courses/functional-javascript/ Hardcore Functional Programming in JavaScript
  78. Thank you. @mark_ jones