Functional Programming
Positive aspects and advantages
Advantages
- clear code in deatils
- easy to test
- distributed/paraller systems
- reusable code
Disadvantages
- unreadable code entirety
- different thinking
Currying
var greet = function(greeting, name) {
console.log(greeting + ", " + name);
};
greet("Hello", "Heidi"); //"Hello, Heidi"
var greetCurried = function(greeting) {
return function(name) {
console.log(greeting + ", " + name);
};
};
greet("Hello")("Heidi"); //"Hello, Heidi"
var greetHello = greetCurried("Hello");
greetHello("Heidi"); //"Hello, Heidi"
greetHello("Eddie"); //"Hello, Eddie"
Currying in real life
var statuses = {
rejected: 'rejected_api',
confirmed: 'comfirmed_ruby_api',
removed: 'removed_attr'
};
function getValue(obj) {
return function(key) {
return obj[key];
}
}
function getKey(obj) {
return function(value) {
return Object.keys(obj).find((key) => obj[key] === value);
}
}
var getStatusValue = getValue(statuses);
var getStatusKey = getKey(statuses);
getStatusValue('rejected') // 'rejected_api'
getStatusKey('comfirmed_ruby_api') // 'confirmed'
Compose
function addTen(num) {
return num + 10;
}
function multiplyByFive(num) {
return num * 5;
}
function convertToArray(num) {
return someMagic(...);
}
var createBigArray = compose(convertToArray, multiplyByFive, addTen);
var myArray = createBigArray(10); // [1, 2, ..., 100]
Compose in real life
function tagSuggestions(element) {
return element.queryAll(By.css('li.list-group-item.suggested-tag'));
}
function selectedTags(element) {
return element.queryAll(By.css('.tag.label.label-primary span.tag-name'));
}
function getItem(num) {
return (array) => array[num];
}
function activeClass(element) {
return element.classes['active'];
}
function suggestion(which) {
return compose(getItem(which), tagSuggestions);
}
function suggestionActive(which) {
return compose(activeClass, getItem(which), tagSuggestions);
}
function selectedTag(which) {
return compose(getItem(which), selectedTags);
}
it('should select second tag', () => {
expect(suggestionActive(0)(el)).toBe(false);
expect(suggestionActive(1)(el)).toBe(true);
expect(suggestionActive(2)(el)).toBe(false);
});
Chain vs Compose
import _ from "lodash";
_.chain([1, 2, 3])
.map(x => [x, x*2])
.flatten()
.sort()
.value();
import map from "lodash/fp/map";
import flatten from "lodash/fp/flatten";
import sortBy from "lodash/fp/sortBy";
import flow from "lodash/fp/flow";
flow(
map(x => [x, x*2]),
flatten,
sortBy(x => x)
)([1,2,3]);