Soul of Functional Programming: Separation and Recognition
- Anything goes
- Everything changes
- Weird names
- custom names
- looping patterns
- glue code
- side effects
- Separate inputs from environment
Secret Input: time (Hard to test)
function daysThisMonth() {
var date = new Date(),
y = date.getFullYear(),
m = date.getMonth(),
start = new Date(y, m, 1),
end = new Date(y, m + 1, 1);
return (end - start) / (1000 * 60 * 60 * 24);
}
Always works the same
function daysInMonth(y, m) {
var start = new Date(y, m - 1, 1),
end = new Date(y, m, 1);
return (end - start) / (1000 * 60 * 60 * 24);
}
Isolate the place where the mutation happen.
Teaser updates DOM
function teaser(size, elt) {
setText(elt, slice(0, size, text(elt)));
}
map(teaser(50), all('p'));
Merely calculates
var teaser = slice(0);
map(compose(setText, teaser(50), text), all('p'));
Functions that don't change anything are called "pure".
- testable
- portable
- memoizable (techinique once you run a function it will memoize and the second time it will return the value and not execute the function)
- parallelizable
function random(m_w, m_z) {
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
return (m_z << 16) + m_w;
}
functions are nouns. We define functions by rules, but think it by nouns. Every function is a single-valued collection of pairs.
separete arity form functions
function get(property, object) {
return object[property];
}
var people = [{name}]
Args up front
function getPersonName(person) {
return get('name', person);
}
var names = people.map(getPersonName)
More args later
// MAGIC!
var names = people.map(get('name'));
Currying: put things one at time.
function curry(fn) {
return function () {
if (fn.length > arguments.length) {
var slice = Array.prototype.slice;
var args = slice.apply(arguments);
return function () {
return fn.apply(
null, args.concat(slice.apply(arguments)));
)
};
}
return fn.apply(null, arguments);
};
}
var get = curry(function (property, object) {
return object[property];
});
var names = people.map(get('name'))