Source: Concepts of Functional Programming in Javascript
Programming paradigm foucsed on building structure and elements
let PI = 3.14;
const calculateArea = (radius) => radius * radius * PI;
calculateArea(10); // returns 314.0
Some functions can’t be pure:
let PI = 3.14;
const calculateArea = (radius, pi) => radius * radius * pi;
calculateArea(10, PI); // returns 314.0
let counter = 1;
function increaseCounter(value) {
counter = value + 1;
}
increaseCounter(counter);
console.log(counter); // 2
let counter = 1;
const increaseCounter = (value) => value + 1;
increaseCounter(counter); // 2
console.log(counter); // 1
var values = [1, 2, 3, 4, 5];
var sumOfValues = 0;
for (var i = 0; i < values.length; i++) {
sumOfValues += values[i];
}
sumOfValues // 15
let list = [1, 2, 3, 4, 5];
let accumulator = 0;
function sum(list, accumulator) {
if (list.length == 0) {
return accumulator;
}
return sum(list.slice(1), accumulator + list[0]);
}
sum(list, accumulator); // 15
list; // [1, 2, 3, 4, 5]
accumulator; // 0
const string = " I will be a url slug ";
const slugify = string =>
string
.toLowerCase()
.trim()
.split(" ")
.join("-");
slugify(string); // i-will-be-a-url-slug
pure functions + immutable data = referential transparency
const doubleSum = (a, b) => (a + b) * 2;
const doubleSubtraction = (a, b) => (a - b) * 2;
// Instead, make simple functions and use them in complex functions!
const sum = (a, b) => a + b;
const subtraction = (a, b) => a - b;
const doubleOperator = (f, a, b) => f(a, b) * 2;
doubleOperator(sum, 3, 1); // 8
doubleOperator(subtraction, 3, 1); // 4
doubleOperator
is higher-order function
Examples:
.filter()
.reduce()
.map()
.reduce()
// Unrefactored code
const friendlyWords = require('friendly-words');
function randomPredicate() {
const choice = Math.floor(Math.random() * friendlyWords.predicates.length);
return friendlyWords.predicates[choice];
}
function randomObject() {
const choice = Math.floor(Math.random() * friendlyWords.objects.length);
return friendlyWords.objects[choice];
}
async function createUser(email) {
const user = { email: email };
user.url = randomPredicate() + randomObject() + randomObject();
await db.insert(user, 'Users')
sendWelcomeEmail(user);
}
// Refactored code
const friendlyWords = require('friendly-words');
const generateURL = user => {
const pick = arr => arr[Math.floor(Math.random() * arr.length)];
user.url = `${pick(friendlyWords.predicates)}-${pick(friendlyWords.objects)}` +
`-${pick(friendlyWords.objects)}`; // This line would've been too long for linters!
};
async function createUser(email) {
const user = { email: email };
// The URL-creation algorithm isn't important to this function so let's abstract it away
generateURL(user);
await db.insert(user, 'Users')
sendWelcomeEmail(user);
}
if (user.authenticated === false) { return; }