most read
Building Stories
Modo Rua: Redefiniendo el desarrollo de aplicaciones mediante iteración centrada en el usuario Ago 23
Building Stories
NuStories: Adaptación de productos para clientes fanáticos en varios países Oct 30
Culture & Values
Cómo los valores y la cultura de Nu dan forma a los productos que creamos Ago 7
Careers
We are building diverse teams with the most creative and innovative professionals for each position we open.



Durante su charla en Clojure South, Alex Miller, Ingeniero Principal de Software en Nubank, abordó un problema que está en el corazón del trabajo diario de todo desarrollador: las formas tan dolorosas en las que solemos manejar los datos. Nuestra industria está plagada de formatos frágiles, objetos cargados de código repetitivo (como getters y setters) y las constantes complejidades del estado mutable que exigen capa tras capa de protección. Esta fricción no es solo deuda técnica; es un impuesto a nuestra creatividad y a nuestro entusiasmo.
Clojure ofrece una alternativa poderosa a este paradigma. Coloca los datos simples e inmutables y las funciones puras en el núcleo mismo de su filosofía. Se trata de una forma de pensar el software fundamentalmente distinta, más allá de ser solo una sintaxis diferente. Al adoptar este modelo, podemos construir modelos mentales más limpios, más matemáticos e increíblemente poderosos. Este enfoque, como demostró Alex, conduce a sistemas que no solo son más robustos, sino también más gratificantes de crear.
El camino hacia esta forma de programar más simple y potente comienza por repensar una palabra que usamos todos los días: «valor».
Volviendo a lo básico: ¿qué es realmente un «valor»?
Aunque la programación implica manipular diversas entidades, el poder de Clojure proviene de una definición rigurosa de los «valores». Esta distinción está lejos de ser una trivialidad semántica; es el principio de diseño central que le otorga al lenguaje su elegancia característica. En este contexto, un valor representa una categoría específica de datos, definida por propiedades inmutables que cambian la forma en que razonamos sobre el estado.
Según Alex, para que algo sea considerado un verdadero valor, debe poseer cuatro características clave:
Esta definición aclara qué no es un valor. Cosas como los sockets de red, los manejadores de archivos (file handles), los streams y los objetos mutables no pasan esta prueba.
Son procesos o recursos, no hechos. Aquí existe una distinción sutil pero importante: la ruta de un archivo (file path) puede tratarse como un valor, ya que es una descripción inmutable y precisa. Sin embargo, un manejador de archivos, que representa una conexión activa a un recurso cambiante, no puede serlo.
Los beneficios de la inmutabilidad
Adoptar la inmutabilidad para todos los valores, incluyendo las colecciones, tiene consecuencias profundas que simplifican enormemente el diseño de sistemas:
Sin necesidad de bloqueos (locks) para lectura: Dado que un valor nunca cambia, puedes leerlo desde cualquier número de hilos sin necesidad de bloqueos o sincronización.
Compartir sin miedo: Puedes pasar estructuras de datos libremente entre procesos concurrentes o sistemas distribuidos, con la confianza de que estás compartiendo información y no una fuente potencial de errores.
Caché e historial sin esfuerzo: El almacenamiento en caché se vuelve trivial cuando los datos nunca cambian. También permite funciones potentes como pilas de «deshacer» (undo) o depuración de «viaje en el tiempo», ya que simplemente puedes mantener referencias a estados anteriores.
Este diseño no está exento de costos; es una elección de ingeniería consciente hecha para obtener beneficios inmensos.
Esta poderosa filosofía no es solo para números individuales o cadenas de texto; en Clojure, se extiende a las colecciones mismas que estructuran nuestros datos.
Check our job opportunies
La base fundamental: simplicidad en cuatro colecciones principales
Si Clojure South tuvo un protagonista silencioso, fue el humilde mapa. Esto no es casualidad. Clojure rechaza deliberadamente un ecosistema disperso de tipos de colecciones en favor de una base pequeña y poderosa de cuatro estructuras fundamentales. Esta elección estratégica de priorizar un conjunto mínimo de estructuras de datos fomenta una reutilización y claridad inmensas.
Clojure se basa en cuatro tipos de colecciones primarias, cada una con un propósito estructural distinto:
Lo que hace que estas colecciones sean tan poderosas no es solo que son inmutables, sino que todas son accesibles a través de un vocabulario único y universal de funciones. En muchos lenguajes orientados a objetos, «cada clase inventa un nuevo lenguaje». Para obtener el nombre de un usuario, llamas a user.getFirstName(); para el total de un pedido, order.getTotal(). Esta es una fuente importante de fricción: los desarrolladores deben cambiar de contexto constantemente, aprendiendo un nuevo mini-protocolo para cada objeto que encuentran.
Clojure rechaza esta complejidad personalizada. En su lugar, proporciona un conjunto unificado de funciones —get, keys, vals, seq, count— que funcionan con todos los datos. Este vocabulario común reduce drásticamente la carga cognitiva. Como señaló Alex Miller, una vez que:
Las mismas herramientas funcionan en todas partes, haciendo que los datos se sientan cercanos, transparentes y fáciles de transformar. Este lenguaje común para manipular datos es la llave que desbloquea el algoritmo central, y notablemente simple, de Clojure para resolver problemas.
El algoritmo central de la programación
En el corazón mismo de la charla, Alex presentó la diapositiva clave: un algoritmo simple de dos pasos que resume toda la filosofía de desarrollo de Clojure. Es una idea tan poderosa que puede transformar fundamentalmente la manera en que uno aborda la construcción de software.
Este modelo de dos pasos de «datos entran, datos salen» es profundamente eficaz por varias razones:
Esto puede sonar elegante en teoría, pero su verdadero poder se vuelve evidente cuando se aplica a problemas del mundo real.
De listas de tareas a la música: datos en acción
Para demostrar el algoritmo central en la práctica, Alex presentó una serie de ejemplos diversos, mostrando cómo cualquier dominio puede ser modelado como datos y manipulado mediante funciones.
Una lista de tareas simple
Una tarea no es un objeto con métodos; es simplemente un mapa que contiene claves como :task (tarea), :errand (recado) y :duration (duración). El consejo de Miller aquí es una piedra angular del diseño pragmático en Clojure:
A partir de esta base, surge un patrón común: escribir una función pequeña para manejar un solo elemento y luego otra para manejar la colección. La tarea de transformar elementos de una lista en HTML sigue esto a la perfección, con una función que convierte un solo mapa en una estructura de datos de Hiccup, y una segunda que aplica esa función (mapping) sobre una colección. Este énfasis en funciones pequeñas de propósito único es omnipresente. Como observó Miller: «no es raro mirar un código base de Clojure y ver que… el tamaño promedio de una función es de cinco líneas».
El Juego de la Vida de Conway
La cuadrícula infinita del Juego de la Vida de Conway se representa elegantemente no con una matriz masiva bidimensional de ceros y unos, sino con una representación dispersa: un conjunto (set) simple que contiene las coordenadas [x, y] de las celdas «vivas». Esta elección de modelado de datos es increíblemente poderosa. Toda la lógica del juego se convierte en un flujo (pipeline) de funciones puras que recibe un conjunto de coordenadas como entrada y produce el siguiente conjunto como salida, implementando las reglas del juego con claridad matemática.
Gráficos y música como datos
El patrón se extiende incluso a dominios creativos. Un círculo en una pantalla puede representarse como un mapa con las claves :x, :y, :radius y :color. Del mismo modo, una nota musical puede ser un mapa con :pitch (tono), :octave (octava) y :duration. Al modelar estas entidades como datos, Alex Miller pudo construir un mini-sintetizador en el escenario, utilizando una secuencia de mapas para tocar el icónico tema de cinco notas de «Encuentros cercanos del tercer tipo».
En cada caso, la solución no se encontró diseñando jerarquías de clases complejas, sino preguntándose primero: «¿Cuál es la estructura de datos más simple que puede representar este problema?», y luego aplicando funciones simples y combinables para transformarla.
Si bien este modelo cubre la gran mayoría de las tareas de programación, Clojure también proporciona un enfoque basado en principios para esos raros momentos en los que los valores realmente necesitan cambiar con el tiempo.
Gestionando cambios: un enfoque basado en principios para el estado
Inevitablemente, algunas partes de una aplicación necesitan cambiar. La sesión de un usuario, una conexión de base de datos, el estado de un componente de interfaz; todo esto requiere gestionar cambios a lo largo del tiempo. Para estos escenarios, Clojure ofrece una respuesta clara que evita el caos de la mutabilidad no gestionada. El objetivo es crear una «identidad lógica estable que tendrá diferentes valores inmutables a lo largo del tiempo».
Clojure ofrece un conjunto pequeño de constructos de estado para este fin, principalmente atoms, refs y agents. En lugar de mutar directamente el valor que contienen, se les proporciona una función pura que calcula el próximo estado a partir del actual. Este diseño significa que los desarrolladores no realizan bloqueos manuales (locking); las lecturas siempre están disponibles sin coordinación y las escrituras son gestionadas de forma segura por el entorno de ejecución (runtime) de Clojure.
Lo más revelador es cómo esto se aplica en la práctica. Cuando se creó Clojure, su sistema de Memoria Transaccional de Software (STM), construido alrededor de las refs, era visto como una característica fundamental. Sin embargo, tras años de uso en producción, surgió una verdad sorprendente. Como observó Miller, los desarrolladores descubrieron que «es posible sobrevivir con una cantidad increíblemente pequeña de estado en tu sistema». El enfoque disciplinado, que prioriza los datos, conduce naturalmente a arquitecturas donde la gran mayoría del código es puro y sin estado, reforzando la filosofía central del lenguaje.
Conclusión: construir sobre la roca, no sobre la arena
El mensaje central de la charla de Alex es un llamado al retorno a la simplicidad. La filosofía es clara: construye sistemas sobre una base de valores inmutables y funciones puras, y gestiona el estado solo cuando sea absolutamente necesario. Este enfoque da como resultado programas más fáciles de entender, evolucionar y mantener.
Miller concluyó con una metáfora poderosa que captura perfectamente la diferencia entre este enfoque y los paradigmas convencionales, cargados de estados mutables. Seguir esta filosofía es como «construir sobre la roca en lugar de construir sobre la arena».
La estabilidad y la claridad que surgen de esta base no son solo logros técnicos; son la fuente de una verdadera satisfacción profesional. Esto permite que los desarrolladores se concentren en resolver problemas en lugar de luchar contra la complejidad accidental de sus herramientas. La ovación de pie que recibió Alex no fue solo por una charla bien ejecutada, sino por articular una filosofía que devuelve la alegría al oficio de la programación.
Check our job opportunies