JavaScript functional concepts
There are so many great things to learn from this video from Bodil Stokke, probably the coolest programmer since Ryan Dahl, or maybe even John Resig :). Unfortunately Bodil is not a fan of JavaScript, preferring languagues like Clojure or Haskell, however has some great talks on ClojureScript and CoffeeScript.
<b>Combinators</b>
Bodil shows us how to create a null combinator in JavaScript. The null combinator allows us to check a null value and can be used to create null safe versions of methods. Of course there are heaps of libraries with extensions for this, like Underscore _.isUndefined, but a combinator function allows us to define a function with type safety, in Bodil's example a nullSagePonyType function.
var dash = null;
var pinkie = {name: 'Pinkie Pie', type: 'Earth Pony'}
function ponyType(pony){
return pony.type;
}
function nullCheck(func){
return function(x){
if(x === null || typeof x === "undefined"){
} return null;
else return func(x)
}
}
var nullSafePonyType = nullCheck(ponyType);
nullSafePonyType(pinkie);
// "Earth Pony"
nullSafePonyType(dash);
// null
<b>Functor - Map</b>
Bodil shows us how to create a simple map function, which is an example of a functor... Now we sound like real functional programmers.
var ponies = [ "Rainbow Dash", "Pinkie Pie"];
function CAPS(s) {
return s.toUpperCase();
}
function map(func, list) {
var newList = [], i;
for(i = 0; i < list.length; i++){
newList.push(func(list[i]));
}
return newList;
}
map(CAPS, ponies);
// RAINBOW DASH, PINKIE PIE
<b>Functor - Filter</b>
Bodil shows us how to create a simple filter function, to filter out Pinkie Pie, who is too cool for the pony list.
var ponies = [ "Rainbow Dash", "Pinkie Pie", "Twilight Sparkle"];
function tooCool(s) {
return s !== "Rainbow Dash";
}
function filter(func, list){
var newList = [], i;
for (i = 0; i = list.length; i++){
if(func(list[i])){
newList.push(list[i]);
}
}
return newList;
}
filter(tooCool, ponies);
// "Pinkie Pie", "Twilight Sparkle"
<b>Catamorphism - Reduce</b>
Bodil shows us that a simple reduce function, is also knows to functional programmers as a Catamorphism, which I think we can all agree is a nice name. Bodil clarifies that a catamorphism is actually a right reduction.
function add(a, b) {
return a + b;
}
function reduce(func, list, initial){
var result = initial, i;
for(i = 0; i <list.length; i++){
result = func(result, list[i]);
}
return result;
}
reduce(add, [1,2,3,4,5], 0)
// 15
<b>Composition</b>
This example of Composition using TypeScript where an operation that produces a new function by nesting functions.
function CAPS(s) {
return s.toUpperCase();
}
function hi(s) {
return "Hello " + s + "!";
}
function compose(func1, func2) {
return function(x){
return func2(func1(x));
}
}
compose(hi, CAPS)("every pony");
<b>Applicative functors</b>
Applicative functors sound pretty confusing, but as we see here, they can be an awesome way to make ponies hug.
function amap(funcs: function[], ...lists: any[]) {
var newList = [], i;
for(i = 0; i < funcs.length; i++){
newList = newList.concat(amap(funcs[i], [], lists));
}
return newList;
}
var ponies = ["Rainbow Dash", "Pinkie Pie"];
var morePonies = ["Applejack", "Rarity"];
function hug(p1, p2){
return p1 + " hugs " + p2;
}
amap([hug], ponies, morePonies);
<b>Currying</b>
Bodil explains that we should really call this Shonfinkeling as the concept originated from Moses Shonfinkel. Here is a simple example of currying using TypeScript.
function curry(func, arity) {
return function(x) {
if(arity === 1){
return func(x);
} else {
return curry(func.bind(null, x), arity - 1);
}
};
}
function add(...args: number[]){
return args.reduce(function(a,b) { return a = b;})
}
curry(add, 3)(1)(2)(3); // 6
Keep an eye out for more of Bodil's talks because they are all very interesting, and quite funny.