Programación

Funcional

en JavaScript

Por Sergio Daniel Xalambrí | @sergiodxa

¿Qué es la programación funcional?

Es un paradigma de programación centrado en el uso de funciones en vez de los cambios de estado.

Programación imperativa

Programación declarativa

En programación imperativa el programador tiene que preguntarse el "como" hacer algo.

En programación declarativa el programador tiene que preguntarse "que" hay que hacer.

const numbers = [1,4,6,7];
const doubles = [];
for (let i = 0; i < numbers.length; i++) {
  const number = numbers[i];
  const double = number * 2;
  doubles.push(double);
}
console.log(doubles); // [2,8,12,14]
const numbers = [1,4,6,7];
const doubles = numbers.map(number => {
  return number * 2
});
console.log(doubles); // [2,8,12,14]

Ejemplos

Conceptos de la Programación Funcional

Funciones de primera clase y

de orden superior

const sayHello = () => 'Hello world';
console.log(sayHello()); // 'Hello world'

Las funciones son datos por lo que se pueden guardar en variables y constantes.

Composición de funciones

const arr1 = [1,2,3];
const arr2 = arr1.map(x => ++x);
console.log(arr2); // [2,3,4]

Las funciones pueden recibír otra función como argumento o devolver una función.

Funciones puras

const numbers = [1,2,3,4,5];
const even    = numbers.filter(n => n % 2 === 0);
console.log(numbers); // [1,2,3,4,5]
console.log(even); // [2,4]

No tienen efectos secundarios, impactan al resto del programa según su resultado y son impactadas por el resto del programa según sus argumentos.

Funciones encapsuladas

function addExclamation(str) {
  const n = random(1,3);
  if (n === 1) return str + '!';
  if (n === 2) return `${str}!`;
  if (n === 3) return str.concat('!');
}
const text = addExclamation('Hello world');
console.log(text); // Hello world!

Las funciones son como cajas negras que reciben argumentos y devuelven datos.

Las funciones son deterministas

function addExclamation(str) {...}
const text1 = addExclamation('Hello world');
const text2 = addExclamation('Hello world');
console.log(text1 === text2); // true

Siempre vas a obtener el mismo resultado con los mismos datos.

Los datos sin inmutables

const str1 = 'hello world';
const str2 = str1.toUpperCase();
console.log(str1); // hello world
console.log(str2); // HELLO WORLD

Una vez que un objeto es creado este no se puede modificar, si necesitas modificarlo tenés que crear una copia.

Currying

function sendMessage(message, name) {
  return `${name}: ${message}`;
}
function sendMessageFrom(name) {
  return function(message) {
    return sendMessage(message, name);
  }
}
const sendMessageFromSergio = sendMessageFrom('Sergio');
const message = sendMessageFromSergio('Hello world')
console.log(message); // Sergio: Hello world

Es el proceso de transformar una función con múltiples argumentos en una que con menos argumentos devuelva una función que acepte el resto.

Mónadas

function pipe(valor, functions) {
  functions.forEach(fn => {
    valor = fn(valor);
  });
  return valor;
}
function squared(v) {
  return v * v;
}
function halved(v) {
  return v / 2;
}
console.log(pipe(4, [squared, halved])); // 8

Estructura de datos que representa cálculos que describen una secuencia de pasos.  

Recurrencia

function fibonacci(max, prev = 0, actual = 1) {
  if (actual + prev >= max) {
    return actual;
  }

  return fibonacci(max, actual, actual + prev);
}

console.log(fibonacci(1000)); // 987

Un proceso que, para completarse, se ejecuta a si mismo.

Beneficios de la programación funcional

Modularización

Al separar tu código en funciones puras favorecemos la modularización y reutilización de código

Mayor legibilidad

Al estar tu código dividido en múltiples funciones muy simples es más fácil seguír el proceso de transformación de datos.

Pruebas más fáciles

Realizar pruebas unitarias sobre funciones puras es más fácil que sobre funciones no puras.

Sin embargo no todo es color de rosas

La programación funcional no sirve para hacer UIs

¿Como se soluciona?

Programación Funcional Reactiva

Programación Funcional + Programación Reactiva

Programación Reactiva

Es un paradigma de programación orientado a los flujo de los datos y la propagación de cambios.

Uniendo la programación funcional y la programación reactiva podemos trabajar sobre flujos de datos dinámicos de forma funcional usando funciones puras.

Programación Funcional Reactiva

Conceptos de FRP

Iterator

Iteramos sobre una colección estática de datos. En cada ciclo del iterador le pedimos a la colección otro dato.

Observer

Nos quedamos una colección de datos dinámica y en cada cambio la colección nos avisa de los nuevos datos.

Patrones comunes

Observable

Es un flujo de datos dinámico e iterable que cada vez que haya un nuevo dato nos avisa y podemos transformar esta colección de forma funcional.

Un evento o una conexión por WebSockets son Observables. 

Ejemplo FRP

import Rx from 'rx';


const $searchInput = document.querySelector('input[type="search"]');


const source = Rx.Observable
                   .fromEvent($searchInput, 'keypress')
                     .filter(event => event.target.value.length > 3)
                     .debounce(500);


source.subscribe(event => {
  console.log(event.target.value);
}, error => {
  console.error(error);
});

Más información

Artículos

Charlas

En inglés

En español

¿Preguntas?

Programación Funcional en JavaScript

By Sergio Xalambrí

Programación Funcional en JavaScript

Presentación sobre los distintos conceptos de programación funcional con ejemplos, terminando con una explicación resumida de FRP.

  • 2,279