Joe Buza
Functional code is characterised by one thing: the absence of side effects. It doesn’t rely on data outside the current function, and it doesn’t change data that exists outside the current function - Mary Rose Cook
produces abstraction through clever ways of combining functions.
produces abstraction through clever ways of combining functions. - Marijn Haverbeke
var x = 10, y = 5;
function add(){
return (x + y);
}
add() has side effects:
when a procedure changes a variable from outside its scope.
var x = 10, y = 5;
function add(){
log(x + y);
return x + y;
}
function log(v){
console.log(v);
}
Impure function
function add(x, y){
return x + y;
}
add(10, 5)
Pure function
Create a program that:
We have a group of developers with experience with particular programming languages.
// sample data
var devs = [{
"name": "Nader",
"langs": ["JS", "Java", "Clojure", "Haskell"]
}, {
"name": "Andrew",
"langs": ["Java", "C", "Objective C", "Swift"]
}, {
"name": "Charles",
"langs": ["C", "C#", "Clojure", "JS"]
}];
// Bad
// Hidden input devs
function getDevs(lang){
var out = [], dev;
for(var i = 0; i < devs.length; i++){
dev = devs[i];
if(dev.langs.indexOf(lang) !== -1){
out.push(dev.name);
}
}
return out;
}
// Better
// No hidden inputs
// Using Array method forEach
function getDevs(devs, lang){
var out = [];
devs.forEach(function(dev){
if(dev.langs.indexOf(lang) !== -1){
out.push(dev.name);
}
});
return out;
}
// Best
// Using Array methods: Filter, Some and Map
function getDevs(devs, lang){
function filter(it){
return it.langs.some(some);
}
function some(it){
return (it === lang);
}
function map(it){
return it.name;
}
return devs.filter(filter).map(map);
}
// Okay
function getLangPoll(devs){
var langs = [];
devs.forEach(function(dev){
langs = langs.concat(dev.langs);
});
var cs = {};
langs.forEach(function(lang){
if(!cs[lang]){
cs[lang] = 1;
} else{
cs[lang]++;
}
});
return cs;
}
// Better
// Using Array method reduce
function getLangPoll(devs){
function concatLangs(prev, curr){
return prev.concat(curr.langs);
}
function reduceLangs(prev, curr){
if(!prev[curr]){
prev[curr] = 1;
} else{
prev[curr]++;
}
return prev;
}
return devs.reduce(concatLangs,[]).reduce(reduceLangs, {});
}