La programación funcional es un enfoque para resolver problemas con ideas centradas en una excelente cobertura de pruebas, mayor encapsulación de código, reutilización y mantenimiento de sistemas. Clojure no solo tiene un paradigma atractivo, también es un lenguaje de programación funcional consolidado, con total interoperabilidad con Java y una buena pila a su alrededor.

Además, cuando pensamos en la escalabilidad y en la rapidez con la que Nubank tuvo que organizarse y no perder el control de la calidad de los servicios que se estaban creando, una arquitectura bien definida y de alto estándar, para ser utilizada en conjunto con Clojure, fue de gran ayuda para garantizar el éxito de la decisión del lenguaje y el diseño de una cultura para entregar código de una manera más frecuente y confiable.

¿Qué es la programación funcional?

La programación funcional es un estilo de programación que sigue el paradigma funcional y, para quienes no lo saben, los paradigmas son enfoques para resolver problemas y lo que los diferencia es cómo idealizan la solución de un problema.

Descubre las oportunidades

Conceptos y pautas de programación funcional.

Inmutabilidad 

Este es el concepto de no modificar ninguna variable durante la ejecución, de manera que solo tenemos variables que son de solo lectura, entonces, una vez que creas una variable con un valor no modificable, si necesitas usarla, se puede crear una nueva usando el valor de la otra más las otras entradas que deseas proporcionar.

  • Ventaja: Sabes exactamente cuál es la variable en cualquier momento de la ejecución, por lo que la depuración se vuelve más fácil.

La inmutabilidad es la idea clave de la programación funcional

Funciones de Primera Clase

Esta es la idea de que una función en este lenguaje no tiene restricciones ni limitaciones y puede tratarse como una variable.

  • Ventajas: Se puede asignar a variables regulares, se puede pasar como argumentos o como retorno de funciones y se puede incluir en cualquier estructura de datos.

Funciones Puras

Esas son funciones en las que solo tienes un resultado posible basado en una entrada, por lo que siempre puedes hacer una predicción. Por ejemplo, en la función matemática “x + 2 = y”, si “x” es 2, “y” siempre será 4, y esto es exactamente lo que es una función pura.

  • Ventaja: Tu tienes control total sobre las pruebas y garantizas que suceda lo que deseas.

Composición de Funciones 

Como su nombre lo indica, puedes utilizar la composición de funciones para obtener el resultado deseado.

  • Ventaja: Aislar lógicas en muchas funciones pequeñas, lo que aumenta la facilidad para probar y desacoplar lógicas.

Expresiones 

Las funciones siempre deberían devolver algo. La programación funcional no aprueba la creación de funciones de declaración, que tienen resultados nulos, con procedimientos realmente difíciles de controlar y predecir lo que sucede en su interior.

  • Ventaja: Mejorar la cobertura de las pruebas.

Recursiones

Over Loops, por lo que la iteración se realiza basándose en el principio de que no tenemos variables mutables y la recursividad usará el último resultado para aplicar el siguiente sin romper la idea, y también evitando efectos secundarios que son bastante comunes en las interacciones de bucle.

  • Ventaja: Más control sobre el código, ya que no perdemos el control de lo que se hace en cada iteración de un bucle. Reducción de efectos secundarios.

¿Por qué Nubank eligió utilizar Clojure como su principal lenguaje de programación?

Cuando se fundó Nubank, necesitábamos un lenguaje potente que nos ayudara a crear la mejor aplicación de tecnología financiera y queríamos que fuera la mejor en términos de calidad, coherencia y velocidad de desarrollo. Y todas esas ideas quedaron reflejadas en Clojure. Hubo algunas cosas que evaluamos como ventajas:

Lenguaje objetivo

Clojure es directo al grano y muy conciso para crear escenarios complejos, cualidades que lo convierten en un lenguaje totalmente no detallado. Esto nos permitió codificar más en menos tiempo.

¡Excelente cobertura de pruebas! No fueron necesarios equipos de Garantía de Calidad.

Prueba mientras codificamos

Podríamos tener una infraestructura preconfigurada para ejecutar las pruebas al mismo tiempo que la modificábamos, con una cobertura de prueba de casi el 100% de las pruebas unitarias más la prueba de integración. Y todo eso garantizaba la calidad del servicio y de lo hecho, por lo que no necesitábamos tener más gente para validarnos esos escenarios. 

Interoperabilidad de Java

Para aquellos que no conocen bastante bien clojure, el lenguaje está construido sobre la JVM (Java Virtual Machine) por lo que podemos usar todo en ese entorno, como bibliotecas Java, frameworks o cualquier otra implementación con Java. Sin embargo, es un beneficio tener esta vasta tecnología disponible si la necesitamos.

Increíble comunidad y documentación de calidad.

Clojure tiene un gran espacio comunitario, en el que las personas participan en la discusión y evolución del idioma, por lo que es muy fácil para ti comenzar y descubrir dónde necesitas aprender sobre él. Además, la gente que estaba en Nubank cuando todo era sólo un espejismo tenía una gran implicación y cariño con Clojure, por lo que fue una decisión fácil de tomar. 

¿Cómo es que Nubank ha escalado tan bien usando Clojure?

Nubank ha crecido extraordinariamente en los últimos años y la evolución de nuestro constante crecimiento en la parte de ingeniería se debe a la organización y arquitectura técnica que suavizó este proceso de crecimiento.

Arquitectura de microservicios con una arquitectura de software bien definida.

Hoy en día, la arquitectura de microservicios de Nubank tiene alrededor de 1000 microservicios escritos en Clojure. Además, todos los microservicios tienen la misma estructura de carpetas basada en nuestra arquitectura de software definida, Diplomat Architecture. Por lo tanto, es fácil entender cómo funcionan los microservicios y dónde encontrar cosas. Dicho todo esto, esto hace que la escalabilidad sea más fácil, ya que podemos mover ingenieros entre equipos, y ellos solo necesitan aprender el contexto empresarial y cómo se organiza en la arquitectura de microservicios; sin embargo, los servicios en sí son sencillos y muy fáciles de manipular. 

Además, podemos aumentar o disminuir los equipos según las prioridades, sin preocuparnos por el seguimiento de los ingenieros o el tiempo de incorporación.

Tener convenciones de código, arquitectura de software, cultura de pruebas y una gran infraestructura ya preparada para aceptar todo ello permite a los equipos y empresas crecer de una manera más optimizada, centrándose mucho más en la resolución de problemas que en mantener las cosas funcionando en base a las personas.

Descubre las oportunidades