Slide 1

Slide 1 text

Functional Programming using Underscore.js othree @ OSDC 2013

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

me • PhD Candidate • Front End Engineer • On the way learning good from functional programming languages

Slide 4

Slide 4 text

Function of Functional Language • Pure function • First class citizen • Higher order function • ...

Slide 5

Slide 5 text

Pure Function • Side effect free • Same input, same output • ex: trigonometric functions

Slide 6

Slide 6 text

First Class Citizen • Function like variable • ex: function expression var f = function () { /*...*/ };

Slide 7

Slide 7 text

Higher Order Function • Function takes or return functions • ex: event listener

Slide 8

Slide 8 text

http://www.flickr.com/photos/78428166@N00/6036104277/

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

[ { name: 'Gates', gender: 'M', org: 'M$' }, { name: 'Peter' gender: 'M', org: 'Hㄒㄈ' } ]

Slide 11

Slide 11 text

"Mentioned by Gates, Peter, Jobs"

Slide 12

Slide 12 text

var str = "Mentioned by "; for (var i = 0, l = tweeps.length; i < l; ++i) { str += tweeps[i].name; if (i < tweeps.length - 1) { str += ", "; } }

Slide 13

Slide 13 text

[ { name: 'Gates', gender: 'M', org: 'M$' }, { name: 'Peter' gender: 'M', org: 'Hㄒㄈ' } ]

Slide 14

Slide 14 text

[ 'Gates', 'Peter' ]

Slide 15

Slide 15 text

var names = []; for (var i = 0, l = tweeps.length; i < l; ++i) { names.push(tweeps[i].name); }

Slide 16

Slide 16 text

var str = "Mentioned by " + names.join(", ");

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

var str = "Mentioned by " + tweeps.map(function (t) { return t.name; }).join(", ");

Slide 20

Slide 20 text

function prop(name) { return function (object) { return object[name]; }; }

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

Case 2

Slide 23

Slide 23 text

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

Summaries

' }; } }, { getSummary: function () { return {text: 'Summaried'}; } }, ... ]

Slide 24

Slide 24 text

Summaries

Summaried

Summary

Slide 25

Slide 25 text

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; }

Slide 26

Slide 26 text

DOM functions

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

var ul = cull.partial(cull.dom.el, "ul"); var li = cull.partial(cull.dom.el, "li");

Slide 30

Slide 30 text

["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); });

Slide 31

Slide 31 text

http://www.flickr.com/photos/jackhynes/519904699/

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

function func(name) { return function (object) { return object[name](); }; }

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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)))

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

http://www.flickr.com/photos/guerson/5630633727/

Slide 46

Slide 46 text

Functional Programming in JavaScript

Slide 47

Slide 47 text

Native • forEach • map/reduce • filter

Slide 48

Slide 48 text

Functional JavaScript • by Oliver Steele at 2007 • First functional JavaScript Library I know

Slide 49

Slide 49 text

Underscore.js • by Jeremy Ashkenas from DocumentCloud • “Underscore is a utility-belt library for JavaScript that provides a lot of the functional programming support”

Slide 50

Slide 50 text

Lo-Dash • Will talk later

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

GHCJS • by Hamish Mackenzie, Victor Nazarov, Luite Stegeman • Haskell to JavaScript compiler

Slide 54

Slide 54 text

Underscore.js • compose • map/reduce • filter • pluck

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

var str = "Mentioned by " + _(tweeps).pluck('name').join(', ');

Slide 60

Slide 60 text

Still Not Enough • curry, partial • prop, func from above example

Slide 61

Slide 61 text

Lo-Dash

Slide 62

Slide 62 text

Functional Programming using Underscore.js othree @ OSDC 2013.1

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

-

Slide 65

Slide 65 text

@

Slide 66

Slide 66 text

@ -

Slide 67

Slide 67 text

@ -

Slide 68

Slide 68 text

What is Lo-Dash • Underscore.js fork by John-David Dalton, Kit Cambridge, and Mathias Bynens

Slide 69

Slide 69 text

Difference • Better performance • Robust result • Larger file size • AMD supports • Auto chain • More power: cloneDeep, partial, result...

Slide 70

Slide 70 text

_.partial var greet = function(greeting, name) { return greeting + ' ' + name; }; var hi = _.partial(greet, 'hi'); hi('moe'); // ! 'hi moe' http://lodash.com/docs#partial

Slide 71

Slide 71 text

_.result var object = { 'cheese': 'crumpets', 'stuff': function () { return 'nonsense'; } }; _.result(object, 'cheese'); // ! 'crumpets' _.result(object, 'stuff'); // ! 'nonsense' http://lodash.com/docs#result

Slide 72

Slide 72 text

With Lo-Dash

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

Performance?

Slide 76

Slide 76 text

Bad..

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

• Take benefits from functional programming • Not change everything to functional • Library helps, ex: lo-dash

Slide 80

Slide 80 text

References Further Readings

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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