Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Functional Programming using underscore.js
Search
othree
April 20, 2013
Programming
6
1.5k
Functional Programming using underscore.js
othree
April 20, 2013
Tweet
Share
More Decks by othree
See All by othree
How GitHub Supports Vim License Detection, The Five Years Journey
othree
1
1.9k
WAT JavaScript Date
othree
3
1.9k
Modern HTML Email Development
othree
3
2.6k
MRT & GIT
othree
1
2k
YAJS.vim and Vim Syntax Highlight
othree
1
2.7k
Web Trends to 2015
othree
4
310
Transducer
othree
9
2.8k
HITCON 11 Photographer
othree
4
470
fetch is the new XHR
othree
6
3.5k
Other Decks in Programming
See All in Programming
How mixi2 Uses TiDB for SNS Scalability and Performance
kanmo
37
14k
パスキーのすべて ── 導入・UX設計・実装の紹介 / 20250213 パスキー開発者の集い
kuralab
3
790
JavaScriptツール群「UnJS」を5分で一気に駆け巡る!
k1tikurisu
9
1.8k
Amazon ECS とマイクロサービスから考えるシステム構成
hiyanger
2
560
Immutable ActiveRecord
megane42
0
140
仕様変更に耐えるための"今の"DRY原則を考える / Rethinking the "Don't repeat yourself" for resilience to specification changes
mkmk884
0
240
Linux && Docker 研修/Linux && Docker training
forrep
24
4.5k
チームリードになって変わったこと
isaka1022
0
200
dbt Pythonモデルで実現するSnowflake活用術
trsnium
0
160
AWS Organizations で実現する、 マルチ AWS アカウントのルートユーザー管理からの脱却
atpons
0
150
密集、ドキュメントのコロケーション with AWS Lambda
satoshi256kbyte
0
190
なぜイベント駆動が必要なのか - CQRS/ESで解く複雑系システムの課題 -
j5ik2o
11
3.8k
Featured
See All Featured
It's Worth the Effort
3n
184
28k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Build The Right Thing And Hit Your Dates
maggiecrowley
34
2.5k
Unsuck your backbone
ammeep
669
57k
Bootstrapping a Software Product
garrettdimon
PRO
306
110k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2.1k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
Code Reviewing Like a Champion
maltzj
521
39k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
49k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Building Adaptive Systems
keathley
40
2.4k
Writing Fast Ruby
sferik
628
61k
Transcript
Functional Programming using Underscore.js othree @ OSDC 2013
me • @othree • https://blog.othree.net
me • PhD Candidate • Front End Engineer • On
the way learning good from functional programming languages
Function of Functional Language • Pure function • First class
citizen • Higher order function • ...
Pure Function • Side effect free • Same input, same
output • ex: trigonometric functions
First Class Citizen • Function like variable • ex: function
expression var f = function () { /*...*/ };
Higher Order Function • Function takes or return functions •
ex: event listener
http://www.flickr.com/photos/78428166@N00/6036104277/
Take a Look Examples from ‘Pure, functional JavaScript’ http://cjohansen.no/talks/2012/sdc-functional/
[ { name: 'Gates', gender: 'M', org: 'M$' }, {
name: 'Peter' gender: 'M', org: 'Hㄒㄈ' } ]
"Mentioned by Gates, Peter, Jobs"
var str = "Mentioned by "; for (var i =
0, l = tweeps.length; i < l; ++i) { str += tweeps[i].name; if (i < tweeps.length - 1) { str += ", "; } }
[ { name: 'Gates', gender: 'M', org: 'M$' }, {
name: 'Peter' gender: 'M', org: 'Hㄒㄈ' } ]
[ 'Gates', 'Peter' ]
var names = []; for (var i = 0, l
= tweeps.length; i < l; ++i) { names.push(tweeps[i].name); }
var str = "Mentioned by " + names.join(", ");
var names = tweeps.map(function (tweep) { return tweep.name; });
var names = tweeps.map(function (t) { return t.name; });
var str = "Mentioned by " + tweeps.map(function (t) {
return t.name; }).join(", ");
function prop(name) { return function (object) { return object[name]; };
}
var str = "Mentioned by " + tweeps.map(prop("name")).join(", ");
Case 2
[ { getSummary: function () { return { text: 'Summaries',
html: '<p>Summaries</p>' }; } }, { getSummary: function () { return {text: 'Summaried'}; } }, ... ]
<div> <p>Summaries</p> <p>Summaried</p> <p>Summary</p> </div>
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; }
DOM functions
var ul = cull.dom.el("ul"); ul.nodeType === 1 // true https://github.com/culljs/dome/
var ul = cull.dom.el("ul", { className: "bands" }); // var
li = cull.dom.el("li", "Execration"); var ul = cull.dom.el("ul", { className: "bands" }, li);
var ul = cull.partial(cull.dom.el, "ul"); var li = cull.partial(cull.dom.el, "li");
["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); });
http://www.flickr.com/photos/jackhynes/519904699/
buildSummary: function () { return div(this.components.map(function (component) { return p(component.getSummary().text);
})); }
buildSummary: function () { return div(this.components.map(function (component) { return p(component.getSummary().text);
})); } 1
buildSummary: function () { return div(this.components.map(function (component) { return p(component.getSummary().text);
})); } 1 2
buildSummary: function () { return div(this.components.map(function (component) { return p(component.getSummary().text);
})); } 1 2 3
buildSummary: function () { return div(this.components. map(function (component) { return
component.getSummary(); }).map(function (summary) { return summary.text; }).map(function (text) { return p(text); })); }
function func(name) { return function (object) { return object[name](); };
}
buildSummary: function () { return div(this.components. map(func("getSummary")). map(function (summary) {
return summary.text; }).map(function (text) { return p(text); })); }
buildSummary: function () { return div(this.components. map(func("getSummary")). map(prop("text")). map(function (text)
{ return p(text); })); }
buildSummary: function () { return div(this.components. map(func("getSummary")). map(prop("text")). map(p)); }
var summarize = compose([p, prop("text"), func("getSummary")]);
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)))
buildSummary: function () { var summarize = compose([p, prop("text"), func("getSummary")]);
return div(this.components.map(summarize)); }
var summarize = compose([p, prop("text"), func("getSummary")]); // ... buildSummary: function
() { return div(this.components.map(summarize)); }
http://www.flickr.com/photos/guerson/5630633727/
Functional Programming in JavaScript
Native • forEach • map/reduce • filter
Functional JavaScript • by Oliver Steele at 2007 • First
functional JavaScript Library I know
Underscore.js • by Jeremy Ashkenas from DocumentCloud • “Underscore is
a utility-belt library for JavaScript that provides a lot of the functional programming support”
Lo-Dash • Will talk later
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
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
GHCJS • by Hamish Mackenzie, Victor Nazarov, Luite Stegeman •
Haskell to JavaScript compiler
Underscore.js • compose • map/reduce • filter • pluck
var str = "Mentioned by " + tweeps.map(prop("name")).join(", ");
var str = "Mentioned by " + _.reduce( _.map(tweeps, function
(t) { return t.name; }), function (memo, name, i) { return (i == 0) ? name : memo + ', ' + name; }, '' );
var str = "Mentioned by " + _(tweeps) .chain() .map(function
(t) { return t.name; }) .reduce(function (memo, name, i) { return (i == 0) ? name : memo + ', ' + name; }, '') .value();
var str = "Mentioned by " + _(tweeps) .map(function (t)
{ return t.name; }) .join(', ');
var str = "Mentioned by " + _(tweeps).pluck('name').join(', ');
Still Not Enough • curry, partial • prop, func from
above example
Lo-Dash
Functional Programming using Underscore.js othree @ OSDC 2013.1
Functional Programming using Underscore.js Lo-Dash othree @ OSDC 2013.1
-
@
@ -
@ -
What is Lo-Dash • Underscore.js fork by John-David Dalton, Kit
Cambridge, and Mathias Bynens
Difference • Better performance • Robust result • Larger file
size • AMD supports • Auto chain • More power: cloneDeep, partial, result...
_.partial var greet = function(greeting, name) { return greeting +
' ' + name; }; var hi = _.partial(greet, 'hi'); hi('moe'); // ! 'hi moe' http://lodash.com/docs#partial
_.result var object = { 'cheese': 'crumpets', 'stuff': function ()
{ return 'nonsense'; } }; _.result(object, 'cheese'); // ! 'crumpets' _.result(object, 'stuff'); // ! 'nonsense' http://lodash.com/docs#result
With Lo-Dash
var summarize = compose([p, prop("text"), func("getSummary")]); // ... buildSummary: function
() { return div(map(summarize), this.components); }
var summarize = _.compose( p, _.partialRight(_.result, 'name'), _.partialRight(_.result, 'getSummary') );
// ... buildSummary: function () { return div(_.map(this.components, summarize)); }
Performance?
Bad..
http://jsperf.com/for-vs-foreach/71
http://jsperf.com/for-vs-foreach/71
• Take benefits from functional programming • Not change everything
to functional • Library helps, ex: lo-dash
References Further Readings
http://interglacial.com/hoj/hoj.html
http://cjohansen.no/talks/2012/sdc-functional/
http://kitcambridge.be/blog/say-hello-to-lo-dash/
http://www.slideshare.net/ihower/fp-osdc2012v2
http://shop.oreilly.com/product/9781593272821.do
http://shop.oreilly.com/product/0636920028857.do
http://shop.oreilly.com/product/0636920028857.do N ot Yet Released
Questions? http://www.flickr.com/photos/roman/5610736/