COMPARTE ESTE ARTÍCULO Y MUESTRA LO QUE APRENDISTE


Desde hace algún tiempo, cada vez más frameworks y desarrolladores han empezado a implementar en sus métodos de trabajo los principios y conceptos de la Programación Funcional, un paradigma de programación declarativa relativamente moderno (para la jerga de la comunidad dev) pero que tiene sus raíces en principios matemáticos y académicos que datan de los años 30s del siglo pasado, principalmente de lo que se conoce como Cálculo lambda, pero que no profundizaremos en este tutorial para concentrarnos únicamente en comprender lo que refieren algunos profesores cuando hablan de Funciones Puras en los cursos de Platzi como Javascript, React, Redux, etc.

Una pizca de Programción Funcional

Antes de definir Programación Funcional haremos una pausa para definir un concepto básico y necesario: el estado(o state) de nuestra aplicación.

En términos muy generales, el estado de una aplicación es el conjunto de variables globales o variables del entorno a las que tienen acceso las funciones, métodos, eventos, etc. de nuestro código, y sobre las cuales pueden efectuarse modificaciones en cualquier momento con o sin un control y seguimiento particular. Es en otras palabras el estado de la memoria en un momento dado y la susceptibilidad de cambiar (mutar) o ser cambiada.

Forman parte del estado global de una aplicación, las variables declaradas en el ámbito global, los elementos, APIs y variables propias del DOM (como el document, localStorage, cache, cookies, la consola, etc.), incluso las bases de datos, los archivos externos (json, txt, etc.), y las REST/APIs -entre otros- … todo esto forma parte del estado global de nuestra aplicación.

Dicho esto, veamos una definición, también muy general de lo que sería entonces la Programación Funcional.

La Programación Funcional es un paradigma de programación en el que no existe (o no se considera) el estado global, no forma parte de la lógica básica de programación. Es decir es una programación sin estado o stateless, en el que no se accede ni se intenta modificar el estado global de una aplicación, sino que por el contrario todo es inmutable. Sólo nos quedaremos con esta idea general, ya que profundizar en un concepto más exacto nos alejaría del objetivo de comprender lo que son groso-modo las funciones puras.

La Programación Imperativa(que es la forma de programar que usamos normalmente) se diferencia de la Programación Funcional -entre otras cosas- en que la segunda está basada en el uso de funciones como centro de toda la lógica programática, mientras que la primera se centra en las Instrucciones o procedimientos (secuencias de instrucciones).

A continuación un breve cuadro comparativo:
Captura de pantalla de 2018-01-04 13-00-10.png

Las funciones (según el paradigma funcional) no son exactamente como las que creamos típicamente en nuestro código, son funciones que deben cumplir condiciones muy particulares que las definen como Funciones Puras.

(Te invito a que investigues luego un poco más sobre este interesante paradigma de desarrollo que poco a poco se está convirtiendo en el nuevo estándar -obligado- de la industria, y que según información reciente, Platzi está preparando todo un Curso al respecto para este año)

Volvamos a lo nuestro.

Las Funciones

Típicamente, una funciónacepta unos valores de entrada, los procesa y produce una salida.

El problema con las funciones estándar (más aún cuando quien las programó, no ha seguido ningún paradigma formal específico) es que no podemos garantizar que el resultado producido sea siempre el mismo para los mismos valores de entrada. En otras palabras, no garantizan que al llamar a la función con los mismos parámetros, el resultado sea consistentemente igual, agregando una innecesaria incertidumbre y complejidad a la lógica del código.

Funciones Puras

Para que una función sea considerada pura debe cumplir dos condiciones fundamentales:

1- Dados los mismos parámetros de entrada, debe retornar +siempre+ el mismo valor de salida, sin importar cuántas veces se llame.

Por ejemplo:

function raizCuadrada( n ){ return Math.sqrt( n ) }
// – o
function esDivisible( n, m ){ return n % m === 0 }

Un ejemplo de una función que no cumpla esta condición sería:

function mesActual(){ return  ( newDate() ).getMonth() + 1 }

En segundo lugar, la función NO debe tener efectos colaterales (o secundarios); es decir, no debe tener ningún otro efecto en el entorno, aparte del cálculo del resultado.

Por ejemplo:

var sesionIniciada = false;

function diaSemana( d, idioma ){
	const _diasEspanol = [ ‘lunes’, ’martes’, ’miercoles’, ’jueves’, ’viernes’, ’sabado’, ’domingo’ ]
	const _diasIngles  = [ ‘monday’, ’tuesday’, ’wednesday’, ’thursday’, ’friday’, ’saturday’, ’sunday’ ]
	if ( idioma == ‘ingles’ ) { 
		return _diasInlges[ d ]
	} else { 
		return _diasEspanol[ d ] 
	}
}

Como verás, a pesar de que la función internamente realiza varias instrucciones para obtener el resultado, estas instrucciones no tienen ningún efecto fuera de dicha función, no alteran o modifican nada en el entorno.

Sin embargo, si a esta función le agregamos una sola línea, por ejemplo …

var sesionIniciada = false;

function diaSemana( d, idioma ){
	const _diasEspanol = [ ‘lunes’, ’martes’, ’miercoles’, ’jueves’, ’viernes’, ’sabado’, ’domingo’ ]
	const _diasIngles  = [ ‘monday’, ’tuesday’, ’wednesday’, ’thursday’, ’friday’, ’saturday’, ’sunday’ ]

// --- modificando el estado de la aplicación
	document.cookie = "diaSemana = " + d; // ---alterando el estado global
	sesionIniciada  = true; // cambiando variable del estado global
// ---
	if ( idioma === ‘ingles’ ) { 
		return _diasInlges[ d ]
	} else { 
		return _diasEspanol[ d ] 
	}
}

Al crear una cookie, modificar variables globales, acceder a una base de datos, etc. etc. … o incluso simplemente al mostrar un mensaje en la consola con console.log(…) ya dejaría de ser una función pura, porque estaría modificando el estado del entorno, provocando efectos colaterales, no relacionados con devolver el resultado que se le ha pedido.

LISTO.

Con esto debes tener ya al menos una idea básica de lo que es una Función Pura; sin embargo, este tema, al igual que toda la teoría relacionada con el paradigma de Programación Funcional es mucho más amplio y complejo, y evidentemente sólo hemos visto lo mínimo necesario para tener una idea de lo que son este tipo de funciones.

Pero … te preguntarás

¿Y cuál es la ventaja de usar Funciones Puras en lugar de seguir programando las funciones como lo venía haciendo hasta ahora?

Te dejo una lista con algunas de las ventajas …

  • Son más fácilmente testeables, ya que van a retornar el mismo resultado a partir de los mismos parámetros.
  • Pueden ser cacheadas, ya que siempre retornan el mismo resultado podemos almacenar estos resultados en cache (memoizar)
  • Más faciles de entender: Se puede reemplazar la función por su valor de resultado, lo que las hace referencialmente transparentes.
  • Se pueden ejecutar en paralelo, ya que no tienen ninguna dependencia externa.
  • Reduce la cantidad de bugs, ya que no generan alteraciones del estado externo.
  • Si no se utiliza el resultado de una expresión pura, se puede eliminar sin afectar a otras expresiones.

En fin, son muchas las ventajas, no solamente de usar funciones puras en tu código, sino de empezar a estudiar, conocer e implementar el paradigma de la Programación Funcional.

Adaptarse a las actualizaciones y los cambios en las prácticas y paradigmas de programación, es fundamental para la supervivencia profesional, más aún en este ecosistema tan dinámico y competitivo.


Como siempre, si te ha gustado este post, recuerda hacer clic en la manito. Bai! 🤓🤘


Referencias:

COMPARTE ESTE ARTÍCULO Y MUESTRA LO QUE APRENDISTE

0 Comentarios

para escribir tu comentario

Artículos relacionados