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]);
					

JS Libraries

Useful Resources