Last active
August 29, 2015 14:19
-
-
Save kamilio/6ae46e0cc1ea47a8c8be to your computer and use it in GitHub Desktop.
Programming with Functions - Stuttgart JS Meetup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// *************************** | |
// Programming with functions (Kamil Jopek) | |
// Stuttgart JS Meetup Talk (13th April 2015) | |
// *************************** | |
// Basic functions | |
var add = function(a, b) { | |
return a + b; | |
}; | |
var multiply = function(a, b) { | |
return a * b; | |
}; | |
var square = function(a) { | |
return a * a; | |
}; | |
// convert arguments object into real array | |
var array = function(args) { | |
return Array.prototype.slice.call(args); | |
}; | |
// *************************** | |
// Encapsulation with closure | |
// *************************** | |
var generateIterator = function(num) { | |
var i = num || 0; | |
return function() { | |
return i++; | |
}; | |
}; | |
var iterator = generateIterator(6); | |
// *************************** | |
// Map/Reduce | |
// *************************** | |
var map = function(fn, array) { | |
var result = []; | |
for (var i = 0; i < array.length; i++) { | |
result[i] = fn.call(this, array[i]); | |
} | |
return result; | |
}; | |
var reduce = function(fn, memo, array) { | |
for (var i = 0; i < array.length; i++) { | |
memo = fn.call(this, array[i], memo); | |
} | |
return memo; | |
}; | |
// *************************** | |
// Compose | |
// *************************** | |
var composeNaive = function(f, g) { | |
return function(value) { | |
return f(g(value)); | |
}; | |
}; | |
var compose = function(/*functions*/) { | |
var functions = array(arguments).reverse(); | |
return function(value) { | |
for (var i = 0; i < functions.length; i++) { | |
value = functions[i].call(this, value); | |
} | |
return value; | |
}; | |
}; | |
// *************************** | |
// Reverse and pipeline | |
// *************************** | |
var reverse = function(fn) { | |
return function(/*arguments*/) { | |
var args = array(arguments).reverse(); | |
return fn.apply(this, args); | |
}; | |
}; | |
var pipeline = reverse(compose); | |
// *************************** | |
// Partial application | |
// *************************** | |
var partial = function(/*function, arguments*/) { | |
var originalArgs = array(arguments), | |
fn = originalArgs.shift(); | |
return function(/*arguments*/) { | |
return fn.apply(this, originalArgs.concat(array(arguments))); | |
}; | |
}; | |
// *************************** | |
// Curry | |
// *************************** | |
var curry = function(fn) { | |
function curried(args) { | |
if (args.length >= fn.length) { | |
return fn.apply(this, args); | |
} else { | |
return function() { | |
return curried(args.concat(array(arguments))); | |
} | |
} | |
}; | |
return curried([]); | |
}; | |
// basic example - not real life use case | |
var addFiveNumbers = curry(function(a, b, c, d, e) { | |
return a + b+ c + d + e; | |
}); | |
addFiveNumbers(1, 2, 3)(45)(5); | |
// map reduce with curry - real world use case | |
map = curry(map); | |
reduce = curry(reduce); | |
var people = [ | |
{name: 'Jack', age: 24, cars: 2}, | |
{name: 'Jane', age: 19, cars: 1} | |
]; | |
var get = curry(function(attribute, object) { | |
return object[attribute]; | |
}); | |
// create functions with one argument | |
var mapToCars = map(get('cars')) | |
var sum = reduce(add, 0); | |
// compose them together | |
var sumAllCars = compose(sum, mapToCars); | |
console.log(sumAllCars(people)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment