Pro Yearly is on sale from $80 to $50! »

Functional Programming using underscore.js

C4ce16f549c450f4759eb37f5d5d1a63?s=47 othree
April 20, 2013

Functional Programming using underscore.js

C4ce16f549c450f4759eb37f5d5d1a63?s=128

othree

April 20, 2013
Tweet

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/