Programación tácita o point-free

July 26, 2019

...

Programación tácita o de punto libre (por su nombre en inglés Point Free) es un paradigma o estilo de programación donde nos liberamos del punto, en este caso el argumento o los argumentos de la función. Es una técnica utilizada para la composición de funciones y elimina código boilerplate.

Tal vez la forma más común de escribir funciones como argumento en javascript es la siguiente:

const f = (cb) => {
  // computación muy pesada!
  const resultado = computacionPesada()
  cb(resultado)
}

// luego llamamos a f con una función en el mismo llamado
f((resultado) => {
  // boom! acá esta el resultado!
})

Esto lo hemos visto en jQuery, NodeJS con el continuation passing style, express cuando definimos rutas e incluso aparece en los tutoriales que vemos en internet ya que es la forma más corta quizás? de continuar escribiendo código.

Sin embargo este patrón tiene varios problemas:

  1. El código no es reutilizable.
  2. Aumentamos un nivel de profundidad, lo cual es considerado por la mayoría de desarrolladores un anti-patrón.
  3. Escribirle tests unitarios a esto es una pesadilla.

Veamos una nueva forma de escribir este mismo código, pero ahora démosle un poco de sentido con una función de suma y luego vamos escalando a cosas más complicadas:

const suma = (a, b, cb) => {
  cb(a + b)
}

const despuesDeSuma = (r) => {
  // acá podemos utilizar el resultado
  // aunque este se llama r, pero es para mostrar un punto
}

suma(1, 2, (resultado) => despuesDeSuma(resultado))

Acá movimos un poco nuestro código, creamos una nueva función llamada despuesDeSuma la cual ahora llamamos dentro del mismo llamado de la función suma. Quiero que miren profundamente la última línea, esa donde estamos llamando a la función suma. Esto está mejor, ya podemos reutilizar la lógica pero sin embargo tiene otro problema, estamos creando una función anónima extra (resultado) => despuesDeSuma(resultado) para llamar a nuestra función. Esto es completamente innecesario y aporta a tener código boilerplate, y código que no es necesario no debería ser escrito. Veamos otra forma de escribir esto mismo pero sin el boilerplate:

const suma = (a, b, cb) => {
  cb(a + b)
}

const despuesDeSuma = (r) => {
  // acá podemos utilizar el resultado
  // aunque este se llama r, pero es para mostrar un punto
}

suma(1, 2, despuesDeSuma) // mira que limpio se ve

Sutil, pero un universo de diferencia, vamos a explicar que ganamos con esto:

  1. Nuestro código ya no esta anidado
  2. Podemos ver claramente las variables que utilizan nuestras funciones, en este caso despuesDeSuma tiene acceso solo a r y a variables globales, lo cual acota mucho las posibilidades de errores en nuestra función.
  3. Las variables a las cuales accede son explícitas. Solo puede acceder a r.
  4. Fácil de probar. En el caso de que queramos escribir un test unitario para poder exponer un bug que encontramos en esa función es solo exportar f probar (con mucho cuidado, no deberías probar funciones internas de un módulo a menos que estas sean utilizadas por otros o quieras exponer errores).
  5. Fácil de componer, al ser solo una función es muy fácil de reutilizar.
  6. Menos código que leer, nos vamos a preocupar de que es lo que hace nuestro código y no cómo lo hace.

Espero que les haya gustado este post, no olviden seguirme en twitter y youtube! Links más abajo.


Suscríbete

Suscríbete a la lista para más cursos, posts y videos tutoriales. Prometo no enviarte más de un correo semanal 🙏

Creado por Nicolás Schürmann ingeniero e instructor de software. Cuando no está programando, esta frente a una cámara dictando cursos, creyéndose youtuber o apoyando a sus alumnos. Puedes seguirlo en twitter o también suscribirte a su canal de youtube. Considera comprar sus cursos por este medio y así apoyas al instructor.