Conceitos funcionais de JavaScript

Há tantas coisas boas para aprender com este vídeo de Bodil Stokke, provavelmente o programador mais legal desde Ryan Dahl, ou talvez até mesmo John Resig :). Infelizmente, Bodil não é fã de JavaScript, preferindo linguagens como Clojure ou Haskell, no entanto, tem ótimas palestras sobre ClojureScript e CoffeeScript.

<b> Combinadores </b>

Bodil nos mostra como criar um combinador nulo em JavaScript. O combinador nulo nos permite verificar um valor nulo e pode ser usado para criar versões seguras nulas de métodos. É claro que há muitas bibliotecas com extensões para isso, como Underscore _.isUndefined, mas uma função combinadora nos permite definir uma função com segurança de tipo, no exemplo de Bodil uma função nullSagePonyType.

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 – Mapa </b>

Bodil nos mostra como criar uma função de mapa simples, que é um exemplo de um functor … Agora parecemos verdadeiros programadores funcionais.

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 – Filtro </b>

Bodil nos mostra como criar uma função de filtro simples, para filtrar Pinkie Pie, que é muito legal para a lista de pôneis.

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> Catamorfismo – Reduzir </b>

Bodil nos mostra que uma função simples de redução também é conhecida pelos programadores funcionais como um catamorfismo, que acho que todos concordamos que é um bom nome. Bodil esclarece que um catamorfismo é na verdade uma redução correta.

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> Composição </b>

Este exemplo de composição usando TypeScript é uma operação que produz uma nova função aninhando funções.

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> Functores aplicativos </b>

Os functores aplicativos parecem bastante confusos, mas como vemos aqui, eles podem ser uma maneira incrível de fazer pôneis se abraçarem.

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 explica que deveríamos realmente chamar isso de Shonfinkeling, pois o conceito se originou de Moses Shonfinkel. Aqui está um exemplo simples de currying usando 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

Fique atento para mais palestras de Bodil porque são todas muito interessantes e muito engraçadas.