Andres Bernal

Andres Bernal

Developer.

© 2019

馃檪 Programacion Funcional

OOP

Al hablar de programaci贸n funcional pondr茅 sobre la mesa dos conceptos importantes el primero es resolver problemas por medio de este paradigma, el segundo permite que el valor de salida de una funci贸n dependa de los argumentos que son la entrada a la funci贸n, as铆 eliminando efectos secundarios como los cambios de estado. Para empezar mira este excelente POST:

http://juanmirod.github.io/2017/06/16/introduccion-programacion-funcional-javascript.html

Funciones de Primera Clase Cuando decimos Funciones de Primera Clase no hablamos de una Clase como tal, nos referimos al tipo de dato, por ejemplo: un n煤mero o una cadena de caracteres puede ser una Funci贸n de Primera Clase. Esto significa que podemos tratar Funciones como cualquier tipo de dato (en vez de tomar un n煤mero o cadena), no existe ning煤n m茅todo, palabra clave o algo especial para definirlas, en este caso decimos que las funciones se pueden asignar en una variable, objecto o incluso un vector. Veamos unos simples ejemplos en c贸digo. un n煤mero se puede asignar a una variable y as铆 asignamos una funci贸n retornando un n煤mero:

  var number = function() { return 2120 };
  • Un n煤mero se puede asignar a un espacio en un vector y as铆 una funci贸n:
  var arrayNumbers = [20, function() { return 24 }];
  • Un n煤mero puede ser asignado a un campo de un objeto y as铆 una funci贸n:
  var objectNumbers = {
   number: 22, 
   fun: function() { return 24 }
};
  • Un n煤mero puede ser creado como sea necesario y tambi茅n una funci贸n:
  20 + (function() { return 24 })(); // => 44
  • Un n煤mero puede ser pasado a una funci贸n y as铆 puede hacerlo una funci贸n: un n煤mero puede ser retornado desde una funci贸n y as铆 puede hacerlo una funci贸n:
  function sumFunc(n, f) { return n + f() }
    sumFunc(20, function() { return 24 }); // => 44
  • un n煤mero puede ser retornado desde una funci贸n y as铆 puede hacerlo una funci贸n:
    return 42;
    return function() { return 42 };
    

Como se ve en los ejemplos las Funciones de Primera Clase no tienen nada de especial, solo las tomamos como cualquier otro tipo de dato pero en este caso es una funci贸n retornando un valor. Los 煤ltimos dos ejemplos le llamamos Funciones de Orden Superior que es el siguiente tema a tratar.

Funciones de Orden Superior En esta cap铆tulo del Post vamos a extender nuestra idea de Funciones de Primera Clase, aqui voy a describir que las funciones no solo puede ser asignadas a una variable, objeto, vector o pasadas como cualquier tipo de dato, ellas tambi茅n pueden ser retornadas desde otras funciones. Las Funciones de Orden Superior toman dos acciones claves: toman una funci贸n como un argumento y retorna una funci贸n como un resultado, fundamental para el paradigma de Programaci贸n Funcional, ahora ya estas listo para ver la explicaci贸n en c贸digo! Vamos a desglosar este t贸pico en un programa muy sencillo para su buen entendimiento del mismo, vamos all谩!

var add = function(x) {
    return function(y) {
       return x + y;
    };
};
var sum = add(2);
sum(2); // => 4

Bien, ahora vamos a dividir esta explicaci贸n en partes:

Primero he asignado una funci贸n a una variable llamada add como si fuese un tipo de dato (Funciones de Primera Clase que vimos anteriormente), este tipo de funciones son tambi茅n conocidas como Funciones An贸nimas o algunos lenguajes de programaci贸n se les conoce como Lambda, esta funci贸n an贸nima toma un argumento. Luego dentro del 谩mbito (Es decir, es un closure) de add retornamos otra funci贸n an贸nima con su argumento y as铆 tomando el argumento del closure y la de esta para retornar una suma de los dos argumentos.

Para llamar la funci贸n debemos asignarla a una variable con su respectivo par谩metro a la primera funci贸n (la asignamos a una variable porque no queremos que se ejecute, si solo ejecutamos la primera funci贸n no va a devolver el resultado), luego ejecutamos la segunda funci贸n asignandole su respectivo par谩metro y listo nos devuelve el resultado.

Es algo tedioso llamar las Funciones de Orden Superior (te puedes imaginar si tienes muchas m谩s funciones que este simple ejemplo? xD), para esto usamos una t茅cnica llamada Currying muy usada en el paradigma de Programaci贸n Funcional. Pero que diablos es Currying?

Currying

Currying es una forma de construir funciones por partes mientras que permita la aplicaci贸n parcial de los argumentos de una funci贸n. Es decir podriamos pasar todo los argumentos de una funci贸n en partes y ejecutarla de una vez, muy simple y as铆 reduce la complejidad en el c贸digo, vamos a ejecutar el ejemplo de arriba usando Currying, veamos!

var add = function(x) {
    return function(y) {
        return x + y;
    };
};

add(2)(2); // => 4

Muy simple! as铆 solo tenemos que llamar la funci贸n una sola vez pasandole los argumentos o resto de elementos a las funciones en parcial.

En lenguajes como Haskell, Scala, ya vienen por default con esta feature ya que son lenguajes funcionales totalmente, en cambio en JavaScript no viene por default, la t茅cnica de Currying se aplica como un tipo de truco o hack para hacerlo trabajar como Currying. Sin embargo podemos usar alguna librer铆a Open Source que nos facilite mucho la vida para estos procesos funcionales, voy a tomar el mismo ejemplo pero usando Lodash, vamos alla!


var add = _.curry(function (x, y) {
    return x + y;
})

add(2)(2); // => 4

El m茅todo curry de Lodash toma una funci贸n como argumento (un callback) transformando los argumentos de este callback en una funci贸n Currying. Map, Reduce y Filter Pues si, JavaScript tiene funciones pre-construidas (a partir de ES5) que toman una funci贸n como argumento y retornan un valor y esas funciones son map(), reduce() y filter() para vectores, veamos un ejemplo de cada una tomando esta simple estructuras de datos:

var students = [
    { name: 'Anna', grade: 6 },
    { name: 'John', grade: 4 },
    { name: 'Maria', grade: 9 }
]; 

filter()

students.filter(function(student) {
    return student.grade >= 6;
});

// [ { name: 鈥楢nna鈥, grade: 6 }, { name: 鈥楳aria鈥, grade: 9 } ]

con map()

students.map(function(obj) {
    return obj.name;
}); 

// [ 'Anna', 'John', 'Maria' ]

reduce()

students.reduce(function(sum, student) { 
    return sum + student.grade;
}, 0)
// 19

Encadenando m茅todos Como vemos map(), reduce() y filter() son Funciones de Orden Superior que vienen en el core de JavaScript, estas funciones toman datos de un vector pasandolo al callback y retornan un valor transformado sin mutar el vector original, luego veremos en profundida la parte de las Funciones Puras e Immutabilidad, la pr贸xima parada es para la Composici贸n de Funciones.

students
  .filter(function (student) { 
    return student.grade >= 6 
  })
  .map(function (obj) {
    return obj.name;
  })

// ['Anna', 'Maria']


mas info y autor de este post: https://medium.com/elblogdejavascript/programaci%C3%B3n-funcional-5da872a080fe