$30 off During Our Annual Pro Sale. View Details »

Functional Programming using underscore.js

othree
April 20, 2013

Functional Programming using underscore.js

othree

April 20, 2013
Tweet

More Decks by othree

Other Decks in Programming

Transcript

  1. Functional Programming using Underscore.js othree @ OSDC 2013

  2. me • @othree • https://blog.othree.net

  3. me • PhD Candidate • Front End Engineer • On

    the way learning good from functional programming languages
  4. Function of Functional Language • Pure function • First class

    citizen • Higher order function • ...
  5. Pure Function • Side effect free • Same input, same

    output • ex: trigonometric functions
  6. First Class Citizen • Function like variable • ex: function

    expression var f = function () { /*...*/ };
  7. Higher Order Function • Function takes or return functions •

    ex: event listener
  8. http://www.flickr.com/photos/78428166@N00/6036104277/

  9. Take a Look Examples from ‘Pure, functional JavaScript’ http://cjohansen.no/talks/2012/sdc-functional/

  10. [ { name: 'Gates', gender: 'M', org: 'M$' }, {

    name: 'Peter' gender: 'M', org: 'Hㄒㄈ' } ]
  11. "Mentioned by Gates, Peter, Jobs"

  12. var str = "Mentioned by "; for (var i =

    0, l = tweeps.length; i < l; ++i) { str += tweeps[i].name; if (i < tweeps.length - 1) { str += ", "; } }
  13. [ { name: 'Gates', gender: 'M', org: 'M$' }, {

    name: 'Peter' gender: 'M', org: 'Hㄒㄈ' } ]
  14. [ 'Gates', 'Peter' ]

  15. var names = []; for (var i = 0, l

    = tweeps.length; i < l; ++i) { names.push(tweeps[i].name); }
  16. var str = "Mentioned by " + names.join(", ");

  17. var names = tweeps.map(function (tweep) { return tweep.name; });

  18. var names = tweeps.map(function (t) { return t.name; });

  19. var str = "Mentioned by " + tweeps.map(function (t) {

    return t.name; }).join(", ");
  20. function prop(name) { return function (object) { return object[name]; };

    }
  21. var str = "Mentioned by " + tweeps.map(prop("name")).join(", ");

  22. Case 2

  23. [ { getSummary: function () { return { text: 'Summaries',

    html: '<p>Summaries</p>' }; } }, { getSummary: function () { return {text: 'Summaried'}; } }, ... ]
  24. <div> <p>Summaries</p> <p>Summaried</p> <p>Summary</p> </div>

  25. buildSummary: function () { var div = document.createElement("div"), p; for

    (var i = 0, l = this.components.length; i < l; ++i) { p = document.createElement("p"); p.innerHTML = this.components[i].getSummary().text; div.appendChild(p); } return div; }
  26. DOM functions

  27. var ul = cull.dom.el("ul"); ul.nodeType === 1 // true https://github.com/culljs/dome/

  28. var ul = cull.dom.el("ul", { className: "bands" }); // var

    li = cull.dom.el("li", "Execration"); var ul = cull.dom.el("ul", { className: "bands" }, li);
  29. var ul = cull.partial(cull.dom.el, "ul"); var li = cull.partial(cull.dom.el, "li");

  30. ["a", "br", "code", "div", ...].forEach(function (tagName) { cull.dom.el[tagName] = cull.partial(cull.dom.el,

    tagName); }); // ["a", "br", "code", "div", ...].forEach(function (tagName) { root[tagName] = cull.partial(cull.dom.el, tagName); });
  31. http://www.flickr.com/photos/jackhynes/519904699/

  32. buildSummary: function () { return div(this.components.map(function (component) { return p(component.getSummary().text);

    })); }
  33. buildSummary: function () { return div(this.components.map(function (component) { return p(component.getSummary().text);

    })); } 1
  34. buildSummary: function () { return div(this.components.map(function (component) { return p(component.getSummary().text);

    })); } 1 2
  35. buildSummary: function () { return div(this.components.map(function (component) { return p(component.getSummary().text);

    })); } 1 2 3
  36. buildSummary: function () { return div(this.components. map(function (component) { return

    component.getSummary(); }).map(function (summary) { return summary.text; }).map(function (text) { return p(text); })); }
  37. function func(name) { return function (object) { return object[name](); };

    }
  38. buildSummary: function () { return div(this.components. map(func("getSummary")). map(function (summary) {

    return summary.text; }).map(function (text) { return p(text); })); }
  39. buildSummary: function () { return div(this.components. map(func("getSummary")). map(prop("text")). map(function (text)

    { return p(text); })); }
  40. buildSummary: function () { return div(this.components. map(func("getSummary")). map(prop("text")). map(p)); }

  41. var summarize = compose([p, prop("text"), func("getSummary")]);

  42. var callGetSummary = func("getSummary"); var getText = prop("text"); var summarize

    = compose([p, getText, callGetSummary]); // summarize(obj); // => callGetSummary(obj) // => getText(callGetSummary(obj)) // => p(getText(callGetSummary(obj)))
  43. buildSummary: function () { var summarize = compose([p, prop("text"), func("getSummary")]);

    return div(this.components.map(summarize)); }
  44. var summarize = compose([p, prop("text"), func("getSummary")]); // ... buildSummary: function

    () { return div(this.components.map(summarize)); }
  45. http://www.flickr.com/photos/guerson/5630633727/

  46. Functional Programming in JavaScript

  47. Native • forEach • map/reduce • filter

  48. Functional JavaScript • by Oliver Steele at 2007 • First

    functional JavaScript Library I know
  49. Underscore.js • by Jeremy Ashkenas from DocumentCloud • “Underscore is

    a utility-belt library for JavaScript that provides a lot of the functional programming support”
  50. Lo-Dash • Will talk later

  51. cull.js • by Christian Johansen and Magnar Sveen • “Cull

    is a toolbelt for writing functional javascript.” • Used in the examples above https://github.com/culljs/culljs
  52. LiveScript & prelude.ls • by George Zahariev • A new

    compile to JavaScript language fork from Coco • Stay in this room until tomorrow, Mindos have a talk about LiveScript
  53. GHCJS • by Hamish Mackenzie, Victor Nazarov, Luite Stegeman •

    Haskell to JavaScript compiler
  54. Underscore.js • compose • map/reduce • filter • pluck

  55. var str = "Mentioned by " + tweeps.map(prop("name")).join(", ");

  56. var str = "Mentioned by " + _.reduce( _.map(tweeps, function

    (t) { return t.name; }), function (memo, name, i) { return (i == 0) ? name : memo + ', ' + name; }, '' );
  57. var str = "Mentioned by " + _(tweeps) .chain() .map(function

    (t) { return t.name; }) .reduce(function (memo, name, i) { return (i == 0) ? name : memo + ', ' + name; }, '') .value();
  58. var str = "Mentioned by " + _(tweeps) .map(function (t)

    { return t.name; }) .join(', ');
  59. var str = "Mentioned by " + _(tweeps).pluck('name').join(', ');

  60. Still Not Enough • curry, partial • prop, func from

    above example
  61. Lo-Dash

  62. Functional Programming using Underscore.js othree @ OSDC 2013.1

  63. Functional Programming using Underscore.js Lo-Dash othree @ OSDC 2013.1

  64. -

  65. @

  66. @ -

  67. @ -

  68. What is Lo-Dash • Underscore.js fork by John-David Dalton, Kit

    Cambridge, and Mathias Bynens
  69. Difference • Better performance • Robust result • Larger file

    size • AMD supports • Auto chain • More power: cloneDeep, partial, result...
  70. _.partial var greet = function(greeting, name) { return greeting +

    ' ' + name; }; var hi = _.partial(greet, 'hi'); hi('moe'); // ! 'hi moe' http://lodash.com/docs#partial
  71. _.result var object = { 'cheese': 'crumpets', 'stuff': function ()

    { return 'nonsense'; } }; _.result(object, 'cheese'); // ! 'crumpets' _.result(object, 'stuff'); // ! 'nonsense' http://lodash.com/docs#result
  72. With Lo-Dash

  73. var summarize = compose([p, prop("text"), func("getSummary")]); // ... buildSummary: function

    () { return div(map(summarize), this.components); }
  74. var summarize = _.compose( p, _.partialRight(_.result, 'name'), _.partialRight(_.result, 'getSummary') );

    // ... buildSummary: function () { return div(_.map(this.components, summarize)); }
  75. Performance?

  76. Bad..

  77. http://jsperf.com/for-vs-foreach/71

  78. http://jsperf.com/for-vs-foreach/71

  79. • Take benefits from functional programming • Not change everything

    to functional • Library helps, ex: lo-dash
  80. References Further Readings

  81. http://interglacial.com/hoj/hoj.html

  82. http://cjohansen.no/talks/2012/sdc-functional/

  83. http://kitcambridge.be/blog/say-hello-to-lo-dash/

  84. http://www.slideshare.net/ihower/fp-osdc2012v2

  85. http://shop.oreilly.com/product/9781593272821.do

  86. http://shop.oreilly.com/product/0636920028857.do

  87. http://shop.oreilly.com/product/0636920028857.do N ot Yet Released

  88. Questions? http://www.flickr.com/photos/roman/5610736/