SlideShare a Scribd company logo
Ricky Bobby’s world
A look into the js performance
We’re speed freaks
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
[dahl]
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Perf Paranoia
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
for loop vs foreach search
13,317,048
4,336,225
for loop vs foreach search
13,317,048
4,336,225
for loop vs foreach search
13,317,048
4,336,225
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Speed Maintainability
var result = [];
for(var i=0, len=arr.length; i < len; i++) {
result.push(doSomething(arr[i]));
}
return result;
For loops are faster!
arr.map(doSomething);
MyFramework.CSS
MyFramework.Animations
MyFramework.Http
MyFramework.Socket
PROPERTY LOOKUPS
"Nesting objects in order to use dot notation is a great way to namespace and organize your code. Unfortunately, w
http://www.phpied.com/extreme-javascript-optimization/
MyFramework.Rendering.CSS
MyFramework.Rendering.Animations
MyFramework.Network.Http
MyFramework.Network.Socket
var Fn1 = 0;
var Fn2 = 1;
function nextFibonacci() {
var f1 = Fn1,
f2 = Fn2,
f3 = f1 + f2;
Fn1 = f2;
Fn2 = f3;
return f3;
}
Global Variable Caching
var Fn1 = 0;
var Fn2 = 1;
function nextFibonacci() {
var ret = Fn1 + Fn2;
Fn1 = Fn2;
Fn2 = ret;
return ret;
}
var iterations = Math.floor(values.length / 8);
var leftover = values.length % 8;
var i = 0;
if (leftover > 0){
do {
process(values[i++]);
} while (--leftover > 0);
}
do {
process(values[i++]);
process(values[i++]);
process(values[i++]);
process(values[i++]);
process(values[i++]);
process(values[i++]);
process(values[i++]);
process(values[i++]);
} while (--iterations > 0);
Loop unrolling
values.forEach(processData)
This is a tiny town…
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
”you are not allowed to care about the performance of * unless you
concatenate all your javascript, have it at the bottom, minify your css and
js, gzip all your assets, and losslessly compress all your images. If you
aren’t getting 90+ Page Speed scores, it’s way too early to be thinking
about selector optimization.”
Ricky Bobby's World
Ricky Bobby's World
Angels in the outfield
JavaScript is a single threaded,
interpreted language
Ricky Bobby's World
Meanwhile…
Ricky Bobby's World
Ricky Bobby's World
Ricky Bobby's World
Enter the declarative
Ricky Bobby's World
var result = [];
for(var i=0, len=users.length; i < len; i++) {
if(users[i].name.length > 0) {
result.push(users[i]);
}
}
return result;
users.filter(function(u){
return u.name.length > 0
})
declarative
imperative
59 // src :: FlickrItem -> URL
60 var src = compose(_.get('m'), _.get('media'));
61
62 // srcs :: FlickrSearch -> [URL]
63 var srcs = compose(map(src), _.get('items'));
64
65 // images :: FlickrSearch -> [DOM]
66 var images = compose(map(imageTag), srcs);
67
68 // tags :: FlickrSearch -> [DOM]
69 var tags = compose(toP, _.countBy(_.identity), _.filter(_.isEmpty), chain(split(' '
70
71 // imagesAndTags :: Tuple [DOM] [DOM]
72 var imagesAndTags = liftA2(Tuple, images, tags)
73
74 // widget :: String -> PictureBox
75 var widget = compose(PictureBox, map(imagesAndTags), getJSON, url);
76
77 ///////////////////////////////////////////////////////////////////////////////////
78
79 mconcat([widget('cats'), widget('dogs')]).fork(log, function(x){
80 compose(setHtml($('#flickr')), _.first)(x)
81 compose(setHtml($(‘#tag_cloud')), _.last)(x)
82 });
83 });
PART 2
compose(map(g), map(f)) == map(compose(g, f))
chain(xs).map(f).map(g).value() == chain(xs).map(compose(g, f)).value()
Loop Fusion
Loop Fusion
var bigFirst = compose(map(first), map(capitalize))
var bigFirst = map(compose(first, capitalize))
bigFirst(['ham', 'cake']) // ['H', 'C']
Loop Fusion
var bigFirst = function(xs) {
return chain(xs).map(capitalize).map(first).value()
}
var bigFirst = function(xs) {
return chain(xs).map(compose(first, capitalize)).value()
}
bigFirst(['ham', 'cake']) // ['H', 'C']
It works for Functors and
Monads too!
Shortcut Fusion
// g :: forall b. (t -> b -> b) -> b -> b
reduce(c, n, build(g)) = g(c, n)
Shortcut Fusion
//build :: (forall b. (a -> b -> b) -> b -> b) -> [a]
var build = function(g){
return g(concat, []);
}
//+ map :: (a -> b) -> [a] -> [b]
var map = curry(function(f, xs){
return build(function(c, n){
return reduce(function(acc, x){ return c(f(x), acc); }, n, xs);
});
});
Shortcut Fusion
var sum = reduce(add, 0);
var sqr = function(x) {return x * x }
var sumSqs = compose(sum, map(sqr))
// reduce(function(acc, x){ return add(sqr(x), acc) }, 0);
Shortcut Fusion
var sum = reduce(add, 0);
var sqr = function(x) {return x * x }
var sumSqs = function(xs) {
return chain(xs).map(sqr).sum().value()
// chain(xs).reduce(function(acc, x){ return add(sqr(x), acc) }, 0).value();
}
Good Producers
• List comprehensions
• concat
• foldr
• map
• take
• filter
• partition
• head
• and, or, any, all
• sequence
• sortBy
• zip
• zipWith
• List comprehensions
• Explicit lists
• cons
• concat
• map
• take
• filter
• iterate, repeat
• repeat
• zip
• zipWith
Good Consumers
It works for Functors and
Monads too!
var addTwenty = memoize(function(x) {
return x + 20;
})
Memoization
var addTwenty = memoize(function(x) {
return x + 20;
})
addTwenty(10) // 30
addTwenty(10) // 30 (didn't run)
addTwenty(11) // 31
Memoization
Memoization
var getPosts = memoize(function(id) {
return new Future(function(rej, res) {
$.getJSON('/posts/'+id, res);
});
});
Memoization
var getPosts = memoize(function(id) {
return new Future(function(rej, res) {
$.getJSON('/posts/'+id, res);
});
});
getPosts(2) // Future
getPosts(2) // Future (didn't run)
getPosts(3) // Future
Memoization
var pQuery = $.toIO()
pQuery(".troll") // IO(function(){ return $(".troll") })
pQuery.runIO() // [Dom, Dom]
pQuery.runIO() // [Dom, Dom, Dom]
Ricky Bobby's World
It works for Functors and
Monads too!
Parallel code
f(f(x, y), z) == f(x, f(y, z))
Parallel code
add(add(2, 3), 5) == add(2, add(3, 5))
Parallel code
add(2, 3, 5)
Parallel code
liftA3(fn, A1, A2, A3)
Parallel code
var longCalc // Int -> Future(Int)
var collectResults = curry(function(rslt1, rslt2, rslt3){})
liftA3(collectResults, longCalc(20), longCalc(30), longCalc(10))
Parallel code
var hasName // Attrs -> Validation
liftA3(save, hasName, hasEmail, hasPhone)
It works for Functors and
Monads too!
Compile while you
compose
var characters = [
{ 'name': 'barney', 'age': 36 },
{ 'name': 'fred', 'age': 40 },
{ 'name': 'pebbles', 'age': 1 }
];
var youngest = _.chain(characters)
.sortBy('age')
.map(function(chr) { return chr.name + ' is ' + chr.age; })
.first()
.value();
// → 'pebbles is 1’
Compile while you
compose
var characters = [
{ 'name': 'barney', 'age': 36 },
{ 'name': 'fred', 'age': 40 },
{ 'name': 'pebbles', 'age': 1 }
];
var youngest = _.chain(characters)
.sortBy('age')
.map(function(chr) { return chr.name + ' is ' + chr.age; })
.first()
.value();
// → 'pebbles is 1’
Lazy code
Lazy code
It works for Functors and
Monads too!
Ricky Bobby's World
Just a handful
THANKS!
@drboolean

More Related Content

PPTX
Fact, Fiction, and FP
Brian Lonsdorf
 
PPTX
Lenses
Brian Lonsdorf
 
PDF
Elm: give it a try
Eugene Zharkov
 
PDF
Cycle.js: Functional and Reactive
Eugene Zharkov
 
PDF
Writing Clean Code in Swift
Derek Lee
 
PDF
Minimizing Decision Fatigue to Improve Team Productivity
Derek Lee
 
PPTX
Super Advanced Python –act1
Ke Wei Louis
 
PDF
Mozilla とブラウザゲーム
Noritada Shimizu
 
Fact, Fiction, and FP
Brian Lonsdorf
 
Elm: give it a try
Eugene Zharkov
 
Cycle.js: Functional and Reactive
Eugene Zharkov
 
Writing Clean Code in Swift
Derek Lee
 
Minimizing Decision Fatigue to Improve Team Productivity
Derek Lee
 
Super Advanced Python –act1
Ke Wei Louis
 
Mozilla とブラウザゲーム
Noritada Shimizu
 

What's hot (20)

PPTX
ES6 in Real Life
Domenic Denicola
 
PDF
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
Dmitry Soshnikov
 
KEY
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Masahiro Nagano
 
PDF
Javascript
Vlad Ifrim
 
PDF
Building Real Time Systems on MongoDB Using the Oplog at Stripe
Stripe
 
PDF
Building Real Time Systems on MongoDB Using the Oplog at Stripe
MongoDB
 
PDF
Introduction to cron queue
ADCI Solutions
 
PDF
Building Real Time Systems on MongoDB Using the Oplog at Stripe
MongoDB
 
PDF
EcmaScript 6 - The future is here
Sebastiano Armeli
 
PDF
The Ring programming language version 1.5.2 book - Part 45 of 181
Mahmoud Samir Fayed
 
PDF
はじめてのGroovy
Tsuyoshi Yamamoto
 
PDF
Rust ⇋ JavaScript
Ingvar Stepanyan
 
PDF
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
MongoSF
 
PPT
An Elephant of a Different Colour: Hack
Vic Metcalfe
 
PDF
Jggug 2010 330 Grails 1.3 観察
Tsuyoshi Yamamoto
 
PDF
Coscup2021-rust-toturial
Wayne Tsai
 
PDF
Зависимые типы в GHC 8. Максим Талдыкин
Юрий Сыровецкий
 
PPTX
ES6 Overview
Bruno Scopelliti
 
PPTX
Groovy puzzlers jug-moscow-part 2
Evgeny Borisov
 
PDF
Javascript ES6 generators
RameshNair6
 
ES6 in Real Life
Domenic Denicola
 
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
Dmitry Soshnikov
 
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Masahiro Nagano
 
Javascript
Vlad Ifrim
 
Building Real Time Systems on MongoDB Using the Oplog at Stripe
Stripe
 
Building Real Time Systems on MongoDB Using the Oplog at Stripe
MongoDB
 
Introduction to cron queue
ADCI Solutions
 
Building Real Time Systems on MongoDB Using the Oplog at Stripe
MongoDB
 
EcmaScript 6 - The future is here
Sebastiano Armeli
 
The Ring programming language version 1.5.2 book - Part 45 of 181
Mahmoud Samir Fayed
 
はじめてのGroovy
Tsuyoshi Yamamoto
 
Rust ⇋ JavaScript
Ingvar Stepanyan
 
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
MongoSF
 
An Elephant of a Different Colour: Hack
Vic Metcalfe
 
Jggug 2010 330 Grails 1.3 観察
Tsuyoshi Yamamoto
 
Coscup2021-rust-toturial
Wayne Tsai
 
Зависимые типы в GHC 8. Максим Талдыкин
Юрий Сыровецкий
 
ES6 Overview
Bruno Scopelliti
 
Groovy puzzlers jug-moscow-part 2
Evgeny Borisov
 
Javascript ES6 generators
RameshNair6
 
Ad

Viewers also liked (7)

KEY
Functional js class
Brian Lonsdorf
 
PPT
Js for learning
Brian Lonsdorf
 
PPT
Liftin every day
Brian Lonsdorf
 
PPTX
Millionways
Brian Lonsdorf
 
PPS
Underscore
Brian Lonsdorf
 
PPT
Functional Patterns for the non-mathematician
Brian Lonsdorf
 
KEY
Functional Reactive Programming in Javascript
Brian Lonsdorf
 
Functional js class
Brian Lonsdorf
 
Js for learning
Brian Lonsdorf
 
Liftin every day
Brian Lonsdorf
 
Millionways
Brian Lonsdorf
 
Underscore
Brian Lonsdorf
 
Functional Patterns for the non-mathematician
Brian Lonsdorf
 
Functional Reactive Programming in Javascript
Brian Lonsdorf
 
Ad

Similar to Ricky Bobby's World (20)

KEY
JavaScript Growing Up
David Padbury
 
PDF
How to build a html5 websites.v1
Bitla Software
 
PDF
Message in a bottle
Konstantin Haase
 
PDF
Refactoring to Macros with Clojure
Dmitry Buzdin
 
PDF
Is HTML5 Ready? (workshop)
Remy Sharp
 
PDF
Is html5-ready-workshop-110727181512-phpapp02
PL dream
 
PPTX
Chromium Embedded Framework + Go at Brooklyn JS
quirkey
 
PDF
前端MVC之BackboneJS
Zhang Xiaoxue
 
PDF
Dependency Management with RequireJS
Aaronius
 
PDF
Browsers with Wings
Remy Sharp
 
PPTX
The State of JavaScript (2015)
Domenic Denicola
 
PDF
SproutCore and the Future of Web Apps
Mike Subelsky
 
ZIP
Javascript Everywhere
Pascal Rettig
 
PDF
Intro to HTML5
Jussi Pohjolainen
 
PDF
Phoenix + Reactで 社内システムを 密かに作ってる
Takahiro Kobaru
 
KEY
Spl Not A Bridge Too Far phpNW09
Michelangelo van Dam
 
KEY
Express Presentation
aaronheckmann
 
PDF
Cristiano Betta (Betta Works) - Lightweight Libraries with Rollup, Riot and R...
Techsylvania
 
KEY
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Paulo Ragonha
 
PDF
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
Guy Royse
 
JavaScript Growing Up
David Padbury
 
How to build a html5 websites.v1
Bitla Software
 
Message in a bottle
Konstantin Haase
 
Refactoring to Macros with Clojure
Dmitry Buzdin
 
Is HTML5 Ready? (workshop)
Remy Sharp
 
Is html5-ready-workshop-110727181512-phpapp02
PL dream
 
Chromium Embedded Framework + Go at Brooklyn JS
quirkey
 
前端MVC之BackboneJS
Zhang Xiaoxue
 
Dependency Management with RequireJS
Aaronius
 
Browsers with Wings
Remy Sharp
 
The State of JavaScript (2015)
Domenic Denicola
 
SproutCore and the Future of Web Apps
Mike Subelsky
 
Javascript Everywhere
Pascal Rettig
 
Intro to HTML5
Jussi Pohjolainen
 
Phoenix + Reactで 社内システムを 密かに作ってる
Takahiro Kobaru
 
Spl Not A Bridge Too Far phpNW09
Michelangelo van Dam
 
Express Presentation
aaronheckmann
 
Cristiano Betta (Betta Works) - Lightweight Libraries with Rollup, Riot and R...
Techsylvania
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Paulo Ragonha
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
Guy Royse
 

Recently uploaded (20)

PDF
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
 
PDF
OFFOFFBOX™ – A New Era for African Film | Startup Presentation
ambaicciwalkerbrian
 
PDF
BLW VOCATIONAL TRAINING SUMMER INTERNSHIP REPORT
codernjn73
 
PDF
SparkLabs Primer on Artificial Intelligence 2025
SparkLabs Group
 
PDF
Security features in Dell, HP, and Lenovo PC systems: A research-based compar...
Principled Technologies
 
PDF
CIFDAQ's Market Wrap : Bears Back in Control?
CIFDAQ
 
PDF
Google I/O Extended 2025 Baku - all ppts
HusseinMalikMammadli
 
PDF
Make GenAI investments go further with the Dell AI Factory
Principled Technologies
 
PDF
Presentation about Hardware and Software in Computer
snehamodhawadiya
 
PDF
The Evolution of KM Roles (Presented at Knowledge Summit Dublin 2025)
Enterprise Knowledge
 
PDF
Get More from Fiori Automation - What’s New, What Works, and What’s Next.pdf
Precisely
 
PPTX
What-is-the-World-Wide-Web -- Introduction
tonifi9488
 
PDF
Brief History of Internet - Early Days of Internet
sutharharshit158
 
PDF
Economic Impact of Data Centres to the Malaysian Economy
flintglobalapac
 
PPTX
cloud computing vai.pptx for the project
vaibhavdobariyal79
 
PDF
The Future of Artificial Intelligence (AI)
Mukul
 
PDF
AI-Cloud-Business-Management-Platforms-The-Key-to-Efficiency-Growth.pdf
Artjoker Software Development Company
 
PDF
Structs to JSON: How Go Powers REST APIs
Emily Achieng
 
PDF
The Future of Mobile Is Context-Aware—Are You Ready?
iProgrammer Solutions Private Limited
 
PDF
A Day in the Life of Location Data - Turning Where into How.pdf
Precisely
 
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
 
OFFOFFBOX™ – A New Era for African Film | Startup Presentation
ambaicciwalkerbrian
 
BLW VOCATIONAL TRAINING SUMMER INTERNSHIP REPORT
codernjn73
 
SparkLabs Primer on Artificial Intelligence 2025
SparkLabs Group
 
Security features in Dell, HP, and Lenovo PC systems: A research-based compar...
Principled Technologies
 
CIFDAQ's Market Wrap : Bears Back in Control?
CIFDAQ
 
Google I/O Extended 2025 Baku - all ppts
HusseinMalikMammadli
 
Make GenAI investments go further with the Dell AI Factory
Principled Technologies
 
Presentation about Hardware and Software in Computer
snehamodhawadiya
 
The Evolution of KM Roles (Presented at Knowledge Summit Dublin 2025)
Enterprise Knowledge
 
Get More from Fiori Automation - What’s New, What Works, and What’s Next.pdf
Precisely
 
What-is-the-World-Wide-Web -- Introduction
tonifi9488
 
Brief History of Internet - Early Days of Internet
sutharharshit158
 
Economic Impact of Data Centres to the Malaysian Economy
flintglobalapac
 
cloud computing vai.pptx for the project
vaibhavdobariyal79
 
The Future of Artificial Intelligence (AI)
Mukul
 
AI-Cloud-Business-Management-Platforms-The-Key-to-Efficiency-Growth.pdf
Artjoker Software Development Company
 
Structs to JSON: How Go Powers REST APIs
Emily Achieng
 
The Future of Mobile Is Context-Aware—Are You Ready?
iProgrammer Solutions Private Limited
 
A Day in the Life of Location Data - Turning Where into How.pdf
Precisely
 

Ricky Bobby's World

  • 1. Ricky Bobby’s world A look into the js performance
  • 28. for loop vs foreach search 13,317,048 4,336,225
  • 29. for loop vs foreach search 13,317,048 4,336,225
  • 30. for loop vs foreach search 13,317,048 4,336,225
  • 35. var result = []; for(var i=0, len=arr.length; i < len; i++) { result.push(doSomething(arr[i])); } return result; For loops are faster! arr.map(doSomething);
  • 36. MyFramework.CSS MyFramework.Animations MyFramework.Http MyFramework.Socket PROPERTY LOOKUPS "Nesting objects in order to use dot notation is a great way to namespace and organize your code. Unfortunately, w http://www.phpied.com/extreme-javascript-optimization/ MyFramework.Rendering.CSS MyFramework.Rendering.Animations MyFramework.Network.Http MyFramework.Network.Socket
  • 37. var Fn1 = 0; var Fn2 = 1; function nextFibonacci() { var f1 = Fn1, f2 = Fn2, f3 = f1 + f2; Fn1 = f2; Fn2 = f3; return f3; } Global Variable Caching var Fn1 = 0; var Fn2 = 1; function nextFibonacci() { var ret = Fn1 + Fn2; Fn1 = Fn2; Fn2 = ret; return ret; }
  • 38. var iterations = Math.floor(values.length / 8); var leftover = values.length % 8; var i = 0; if (leftover > 0){ do { process(values[i++]); } while (--leftover > 0); } do { process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); } while (--iterations > 0); Loop unrolling values.forEach(processData)
  • 39. This is a tiny town…
  • 45. ”you are not allowed to care about the performance of * unless you concatenate all your javascript, have it at the bottom, minify your css and js, gzip all your assets, and losslessly compress all your images. If you aren’t getting 90+ Page Speed scores, it’s way too early to be thinking about selector optimization.”
  • 48. Angels in the outfield
  • 49. JavaScript is a single threaded, interpreted language
  • 57. var result = []; for(var i=0, len=users.length; i < len; i++) { if(users[i].name.length > 0) { result.push(users[i]); } } return result; users.filter(function(u){ return u.name.length > 0 }) declarative imperative
  • 58. 59 // src :: FlickrItem -> URL 60 var src = compose(_.get('m'), _.get('media')); 61 62 // srcs :: FlickrSearch -> [URL] 63 var srcs = compose(map(src), _.get('items')); 64 65 // images :: FlickrSearch -> [DOM] 66 var images = compose(map(imageTag), srcs); 67 68 // tags :: FlickrSearch -> [DOM] 69 var tags = compose(toP, _.countBy(_.identity), _.filter(_.isEmpty), chain(split(' ' 70 71 // imagesAndTags :: Tuple [DOM] [DOM] 72 var imagesAndTags = liftA2(Tuple, images, tags) 73 74 // widget :: String -> PictureBox 75 var widget = compose(PictureBox, map(imagesAndTags), getJSON, url); 76 77 /////////////////////////////////////////////////////////////////////////////////// 78 79 mconcat([widget('cats'), widget('dogs')]).fork(log, function(x){ 80 compose(setHtml($('#flickr')), _.first)(x) 81 compose(setHtml($(‘#tag_cloud')), _.last)(x) 82 }); 83 });
  • 60. compose(map(g), map(f)) == map(compose(g, f)) chain(xs).map(f).map(g).value() == chain(xs).map(compose(g, f)).value() Loop Fusion
  • 61. Loop Fusion var bigFirst = compose(map(first), map(capitalize)) var bigFirst = map(compose(first, capitalize)) bigFirst(['ham', 'cake']) // ['H', 'C']
  • 62. Loop Fusion var bigFirst = function(xs) { return chain(xs).map(capitalize).map(first).value() } var bigFirst = function(xs) { return chain(xs).map(compose(first, capitalize)).value() } bigFirst(['ham', 'cake']) // ['H', 'C']
  • 63. It works for Functors and Monads too!
  • 64. Shortcut Fusion // g :: forall b. (t -> b -> b) -> b -> b reduce(c, n, build(g)) = g(c, n)
  • 65. Shortcut Fusion //build :: (forall b. (a -> b -> b) -> b -> b) -> [a] var build = function(g){ return g(concat, []); } //+ map :: (a -> b) -> [a] -> [b] var map = curry(function(f, xs){ return build(function(c, n){ return reduce(function(acc, x){ return c(f(x), acc); }, n, xs); }); });
  • 66. Shortcut Fusion var sum = reduce(add, 0); var sqr = function(x) {return x * x } var sumSqs = compose(sum, map(sqr)) // reduce(function(acc, x){ return add(sqr(x), acc) }, 0);
  • 67. Shortcut Fusion var sum = reduce(add, 0); var sqr = function(x) {return x * x } var sumSqs = function(xs) { return chain(xs).map(sqr).sum().value() // chain(xs).reduce(function(acc, x){ return add(sqr(x), acc) }, 0).value(); }
  • 68. Good Producers • List comprehensions • concat • foldr • map • take • filter • partition • head • and, or, any, all • sequence • sortBy • zip • zipWith • List comprehensions • Explicit lists • cons • concat • map • take • filter • iterate, repeat • repeat • zip • zipWith Good Consumers
  • 69. It works for Functors and Monads too!
  • 70. var addTwenty = memoize(function(x) { return x + 20; }) Memoization
  • 71. var addTwenty = memoize(function(x) { return x + 20; }) addTwenty(10) // 30 addTwenty(10) // 30 (didn't run) addTwenty(11) // 31 Memoization
  • 72. Memoization var getPosts = memoize(function(id) { return new Future(function(rej, res) { $.getJSON('/posts/'+id, res); }); });
  • 73. Memoization var getPosts = memoize(function(id) { return new Future(function(rej, res) { $.getJSON('/posts/'+id, res); }); }); getPosts(2) // Future getPosts(2) // Future (didn't run) getPosts(3) // Future
  • 74. Memoization var pQuery = $.toIO() pQuery(".troll") // IO(function(){ return $(".troll") }) pQuery.runIO() // [Dom, Dom] pQuery.runIO() // [Dom, Dom, Dom]
  • 76. It works for Functors and Monads too!
  • 77. Parallel code f(f(x, y), z) == f(x, f(y, z))
  • 78. Parallel code add(add(2, 3), 5) == add(2, add(3, 5))
  • 81. Parallel code var longCalc // Int -> Future(Int) var collectResults = curry(function(rslt1, rslt2, rslt3){}) liftA3(collectResults, longCalc(20), longCalc(30), longCalc(10))
  • 82. Parallel code var hasName // Attrs -> Validation liftA3(save, hasName, hasEmail, hasPhone)
  • 83. It works for Functors and Monads too!
  • 84. Compile while you compose var characters = [ { 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }, { 'name': 'pebbles', 'age': 1 } ]; var youngest = _.chain(characters) .sortBy('age') .map(function(chr) { return chr.name + ' is ' + chr.age; }) .first() .value(); // → 'pebbles is 1’
  • 85. Compile while you compose var characters = [ { 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }, { 'name': 'pebbles', 'age': 1 } ]; var youngest = _.chain(characters) .sortBy('age') .map(function(chr) { return chr.name + ' is ' + chr.age; }) .first() .value(); // → 'pebbles is 1’
  • 88. It works for Functors and Monads too!