Andres Bedoya G. (A.K.A. Angelfire)
(programming paradigm) Is the process of building software by composing pure functions, avoiding shared state, mutable data, and side-effects. Functional programming is declarative rather than imperative, and application state flows through pure functions.
Functional programming is a declarative paradigm, meaning that the program logic is expressed without explicitly describing the flow control.
Imperative programs spend lines of code describing the specific steps used to achieve the desired results — the flow control: How to do things.
Declarative programs abstract the flow control process, and instead spend lines of code describing the data flow: What to do. The how gets abstracted away.
const doubleMap = numbers => {
const doubled = [];
for (let i = 0; i < numbers.length; i++) {
doubled.push(numbers[i] * 2);
}
return doubled;
};
const doubleMap = numbers => numbers.map(n => n * 2);
Examples of commonly used statements include for, if, switch, throw, etc…
map, filter, reduce, concatAll, zip...
A pure function is a function which:
// impure addToCart mutates existing cart
const addToCart = (cart, item, quantity) => {
cart.items.push({
item,
quantity
});
return cart;
};
const time = () => new Date().toLocaleTimeString();
time(); // "11:20:35 AM"
Math.random(); // 0.13196662441712692
Math.random(); // 0.3356794546270385
Math.random(); // 0.9819770414694777
// Pure addToCart() returns a new cart
// It does not mutate the original.
const addToCart = (cart, item, quantity) => {
const newCart = lodash.cloneDeep(cart);
newCart.items.push({
item,
quantity
});
return newCart;
};
Is the process of combining two or more functions in order to produce a new function or perform some computation. For example, the composition f . g (the dot means “composed with”) is equivalent to f(g(x)) in JavaScript.
const compose = (func1, func2) => (value) => func1(func2(value));
const double = x => x * 2;
const triple = x => x * 3;
const composed = compose(double, triple);
console.log(composed(3)); // 18
Shared state is any variable, object, or memory space that exists in a shared scope, or as the property of an object being passed between scopes. A shared scope can include global scope or closure scopes. Often, in object oriented programming, objects are shared between scopes by adding properties to other objects.
// With shared state, the order in which function calls are made
// changes the result of the function calls.
const x = {
val: 2
};
const x1 = () => x.val += 1;
const x2 = () => x.val *= 2;
x1();
x2();
console.log(x.val); // 6
x2();
x1();
console.log(x.val); // 5
const x = {
val: 2
};
const x1 = x => Object.assign({}, x, { val: x.val + 1});
const x2 = x => Object.assign({}, x, { val: x.val * 2});
console.log(x1(x2(x)).val); // 5
const y = {
val: 2
};
x2(y);
x1(y);
console.log(x1(x2(y)).val); // 5
request 1: updateBio() -> (save button) -> updateUser()
request 2: updateAvatar() -> (save button) -> updateUser()
An immutable object is an object that can’t be modified after it’s created. Conversely, a mutable object is any object which can be modified after it’s created.
const a = {
foo: 'Hello',
bar: 'MDEJS',
baz: '!'
};
a.foo = 'Goodbye';
// 'Goodbye'
const a = Object.freeze({
foo: 'Hello',
bar: 'MDEJS',
baz: '!'
});
a.foo = 'Goodbye';
// Error: Cannot assign to read only property 'foo' of object Object
const a = Object.freeze({
foo: { greeting: 'Hello' },
bar: 'MEDJS',
baz: '!'
});
a.foo.greeting = 'Goodbye';
console.log(`${ a.foo.greeting }, ${ a.bar }${a.baz}`);
A side effect is any application state change that is observable outside the called function other than its return value. Side effects include:
Haskell and other functional languages frequently isolate and encapsulate side effects from pure functions using monads.
A higher order function is any function which takes a function as an argument, returns a function, or both. Higher order functions are often used to:
Functional programming tends to reuse a common set of functional utilities to process data. Object oriented programming tends to colocate methods and data in objects. Those colocated methods can only operate on the type of data they were designed to operate on, and often only the data contained in that specific object instance.
In functional programming, any type of data is fair game. The same map()utility can map over objects, strings, numbers, or any other data type because it takes a function as an argument which appropriately handles the given data type. FP pulls off its generic utility trickery using higher order functions.