Functional Programming
in Javascript
With
LODASH
ED ATRERO
@edatrero


github.com/eatrero
Functional programming (lite)
- Using lots of small functions
- Easier to test
Example



violations = [
{
"uuid" : "916a7bb5-fc2a-4edf-a365-32d599d56366",
"id" : "box1",
"type" : "TOO_LARGE"
},
{
"uuid" : "b3f25844-e5f7-4b60-915e-bd983a3deaed",
"id" : "box1",
"type" : "TOO_LARGE"
},
{
"uuid" : "916a7bb5-fc2a-4edf-a365-32d599d56366",
"id" : "box4",
"type" : "TOO_LARGE"
},
{
"uuid" : "916a7bb5-fc2a-4edf-a365-32d599d56366",
"id" : "box5",
"type" : "TOO_SMALL"
},
{
"uuid" : "916a7bb5-fc2a-4edf-a365-32d599d56366",
"id" : "box7",
"type" : "TOO_SMALL"
},
{
"uuid" : "916a7bb5-fc2a-4edf-a365-32d599d56366",
"id" : "box12",
"type" : "TOO_LARGE"
},
{ ... }
]
filterViolations(violations, 'page2', "916a7bb5-fc2a-4edf-a365-32d599d56366")
// Outputs:
// [{ boxId: 'box4', messageType: 'TOO_LARGE' },
// { boxId: 'box5', messageType: 'TOO_SMALL' },
// { boxId: 'box7', messageType: 'TOO_SMALL' } ]
var pageFilters = { 'page1' : ['box1', 'box2', 'box2b', 'box3'],
'page2' : ['box4', 'box5', 'box6', 'box7', 'box8a', 'box8b'],
'page3' : ['box9', 'box10', 'box11'],
'page4' : ['box12', 'box13'] };
var pageFilters = { 'page1' : ['box1', 'box2', 'box2b', 'box3'],
'page2' : ['box4', 'box5', 'box6', 'box7', 'box8a', 'box8b'],
'page3' : ['box9', 'box10', 'box11'],
'page4' : ['box12', 'box13'] };
var violations = [
{
"uuid" : "916a7bb5-fc2a-4edf-a365-32d599d56366",
"id" : "box1",
"type" : "TOO_LARGE"
},
{ ... } ]
function filterViolationsImp(violations, pageId, uuid){
var i, out=[];
for(i=0; i<violations.length; i++){
if(violations[i].uuid === uuid){
if(pageFilters[pageId].indexOf(violations[i].id) !== -1)
out.push( { "boxId" : violations[i].id, "messageType" : violations[i].type });
}
}
return out;
}
imperative programming
- Familiar
- Efficient
Problems with imperative
When adding additional complexity, code:
- Gets harder to reason about
- Gets harder to test
- Gets harder to maintain (brittle)
Functional approach
var _ = require('lodash');
function filterViolationsChain(violations, pageId, uuid){
return _.chain(violations)
.filter((v) => v.uuid === uuid)
.filter((v) => pageFilters[pageId].indexOf(v.id) !== -1)
.map((v) => ({ "boxId": v.id, "messageType" : v.type }))
.value();
}
function filterViolationsImp(violations, pageId, uuid) {
var i, out=[];
for(i=0; i<violations.length; i++){
if(violations[i].uuid === uuid){
if(pageFilters[pageId].indexOf(violations[i].id) !== -1)
out.push( { "boxId" : violations[i].id, "messageType" : violations[i].type });
}
}
return out;
}
Functional approach
- Easier to reason about
- Easier to modify/maintain
- Easier to test
- Less efficient
“We should forget about small efficiencies, say about 97% of the time; premature optimization is the root of all evil”
DONALD E. KNUTH
filterViolations(violations, ['page1','page2'], "916a7bb5-fc2a-4edf-a365-32d599d56366")
function filterViolationsImp(violations, pageIds, uuid){
var i, j, out=[];
for(i=0; i<violations.length; i++){
if(violations[i].uuid === uuid){
for(j=0; j<pageIds.length; j++){
if(pageFilters[pageIds[j]].indexOf(violations[i].id) !== -1)
out.push( { "boxId" : violations[i].id, "messageType" : violations[i].type });
}
}
}
return out;
}
function filterViolationsChain(violations, pageIds, uuid){
return _.chain(violations)
.filter((v) => v.uuid === uuid)
.filter((v) => violationOnPages(v, pageIds))
.map((v) => ({ "boxId": v.id, "messageType" : v.type }))
.value();
}
function violationOnPages(v, pageIds){
return _.some(pageIds, (p) => pageFilters[p].indexOf(v.id) !== -1);
}

Testing deeply nested code...
Summary
- Functional Programming: create an assembly line of functions (_.chain)
- Easier to reason about (.filter, .map, .some)
- Lots of small functions leads to more testable code
- More testable code leads to higher quality code (lessBugs === happyUsers === '$$$')
Questions?
@edatrero


github.com/eatrero
- https://slides.com/edatrero/
- Code Examples
- Lodash Docs
- Functional JavaScript by Michael Fogus
Functional Programming in JavaScript with Lodash
By Ed Atrero
Functional Programming in JavaScript with Lodash
Frontend Authority Meetup for March 17, 2016
- 2,034