Functional Programming and JavaScript
JavaScript
A high-level, dynamic, untyped, interpreted, multi-paradigm programming language
Paradigms
Object-oriented, imperative, and functional
Origins
In 1936, Alonzo Church and Alan Turing independently developed powerful mathematical models of computation. Turing called his model a-machines, but everyone instantly started calling them Turing machines. Church wrote instead about functions. His model was called, λ-calculus (λ is the lowercase Greek letter lambda). His work was the reason Lisp chose the word LAMBDA to denote functions, which is why we call function expressions 'lambdas' today.
Lambda Calculus
λ-calculus is one of the first programming languages. It was not designed to be a programming language — after all, stored-program computers wouldn’t come along for another decade or two — but rather a ruthlessly simple, stripped-down, purely mathematical idea of a language that could express any kind of computation you wished to do. Church wanted this model in order to prove things about computation in general and he found that he only needed one thing in his system: functions.
Lambda vs JavaScript
fix = λf.(λx.f(λv.x(x)(v)))(λx.f(λv.x(x)(v)))
const fix = f => (x => f(v => x(x)(v)))(x => f(v => x(x)(v)));
λ-calculus
JavaScript
Functional Programming in JS
JavaScript makes it easy to assign functions to variables, pass them into other functions, return functions from other functions, compose functions, etc. These features exist in most languages today simply because JavaScript made them popular and early developers wrote JavaScript libraries that depended heavily on functional programming techniques.
First-class functions
Passing functions as arguments
Anonymous and nested functions
Non-local variables and closures
Returning functions as results
Assigning functions to variables
Equality of functions
Simple lambda syntax
Passing functions as Arguments
const cities = ['San Francisco', 'New York', 'Perth'];
cities.forEach(console.log);
// San Francisco
// New York
// Perth
Anonymous Functions
const numbers = [1, 2, 3, 4, 5];
numbers.map(number => number * number);
// 1
// 4
// 9
// 16
// 25
Closures
function closure() {
const _secret = 'I am a secret.';
return function logSecret() {
console.log(_secret);
}
}
const accessSecret = closure();
accessSecret();
Returning Functions as Results
function closure() {
const _secret = 'I am a secret.';
return function logSecret() {
console.log(_secret);
}
}
const accessSecret = closure();
accessSecret();
Assigning Functions to Variables
// ES6
const difference = (a, b) => a - b;
// ES5
const sum = function (a, b) {
return a + b;
};
Why Functional Programming?
Functional programming supports abstraction, which hides details and gives us the ability to talk about problems at a higher (or more abstract) level. The essence of functional programming is quite simple; programs are primarily built with a handful of small, reusable, and predictable pure functions.
No Abstraction
Abstraction
Why Functional Programming?
vs
Put 1 cup of dried peas per person into a container. Add water until the peas are well covered. Leave the peas in water for 12 hours. Take the peas out of the water and put them in a cooking pan. Add 4 cups of water per person. Cover the pan and keep the peas simmering for two hours. Take half an onion per person. Cut it into pieces with a knife. Add it to the peas. Take a stalk of celery per person. Cut it into pieces with a knife. Add it to the peas. Take a carrot per person. Cut it into pieces with a knife. Add it to the peas. Cook for 10 more minutes.
Per person: 1 cup dried split peas, half a chopped onion, a stalk of celery, and a carrot.
Soak peas for 12 hours. Simmer for 2 hours in 4 cups of water (per person). Chop and add vegetables. Cook for 10 more minutes.
No Abstraction
Abstraction
let total = 0;
let count = 1;
while (count <= 10) {
total += count;
count += 1;
}
console.log(total);
console.log(sum(range(1, 10)));
Why Functional Programming?
vs
ES6 Arrow Functions
Subtitle
// An empty arrow function returns undefined
let empty = () => {};
(() => "foobar")() // returns "foobar"
var simple = a => a > 15 ? 15 : a;
simple(16); // 15
simple(10); // 10
let max = (a, b) => a > b ? a : b;
// Easy array filtering, mapping, ...
var arr = [5, 6, 13, 0, 1, 18, 23];
var sum = arr.reduce((a, b) => a + b); // 66
var even = arr.filter(v => v % 2 == 0); // [6, 0, 18]
var double = arr.map(v => v * 2); // [10, 12, 26, 0, 2, 36, 46]
// More concise promise chains
promise.then(a => {
// ...
}).then(b => {
// ...
});
Example
Abstracting Array Traversal
Exercises
Reject (using filter)
Flatten
Every
Some
Functional Programming
By Benji
Functional Programming
- 279