# Colecciones, transformaciones y recursión en Clojure

En esta segunda semana de Clojure, dejamos atrás la parte más introductoria y entramos a una de las ideas más importantes del lenguaje: trabajar con colecciones de forma funcional.

Cuando empezamos a construir software real, casi todo gira alrededor de recibir datos, transformarlos, filtrarlos y combinarlos para obtener respuestas útiles. En Clojure, esto se hace con una gran claridad gracias a funciones como `map`, `filter`, `reduce` y a la forma natural de manipular maps, vectors, lists y sets.

Source Code: [https://github.com/joedayz/clojure-senior-path/tree/week2](https://github.com/joedayz/clojure-senior-path/tree/week2)

## **1) Las colecciones son el corazón de Clojure**

Clojure está muy centrado en el trabajo con datos estructurados. Las colecciones más comunes son:

```java
(def nums [1 2 3 4 5])
(def fruits '(:manzana :pera :uva))
(def user {:name "Ana" :age 30})
(def tags #{:backend :clojure :functional})
```

Cada una tiene un propósito diferente:

*   Vector: `[...]` → colección ordenada
    
*   Lista: `'(...)` → estructura común en programación funcional
    
*   Map: `{...}` → pares clave/valor
    
*   Set: `#{...}` → valores únicos
    

Esto es importante porque en proyectos reales no solo guardamos valores sueltos; normalmente trabajamos con listas de productos, usuarios, pedidos, métricas, clientes y estados.

## **2) Transformar datos con** `map`

La función `map` aplica una operación a cada elemento de una colección.

```java
(defn double-all
  [numbers]
  (map #(* 2 %) numbers))
```

Uso:

```java
(double-all [1 2 3 4])
;; => (2 4 6 8)
```

Esto parece pequeño, pero es extremadamente útil. En aplicaciones reales, `map` te permite:

*   duplicar precios
    
*   convertir cadenas a mayúsculas
    
*   calcular impuestos
    
*   agregar metadata a cada registro
    
*   aplicar transformaciones a listas completas
    

La belleza de `map` es que expresa claramente: “aplica esta operación a cada elemento”.

## **3) Filtrar con** `filter`

Cuando queremos quedarnos con los elementos que cumplen una condición, usamos `filter`.

```java
(defn even-only  [numbers]
  (filter even? numbers))
```

Uso:

```plaintext
(even-only [123456])
;; => (2 4 6)
```

![](http://localhost:63342/markdownPreview/651830898//Users/josediaz/Projects/JoeDayz/ClojureSaveme/articles align="center")

Este patrón es muy común en negocios y aplicaciones:

*   clientes activos
    
*   pedidos mayores a cierto monto
    
*   productos con precio superior a un umbral
    
*   usuarios con rol específico
    

`filter` no solo simplifica el código; también hace que el propósito sea más fácil de leer.

## **4) Reducir datos con** `reduce`

`reduce` toma una colección y la combina en un solo valor. Es ideal para sumar, acumular, agrupar o construir resultados finales.

```plaintext
(defn sum-numbers  [numbers]
  (reduce +0 numbers))
```

Uso:

```plaintext
(sum-numbers [12345])
;; => 15
```

![](http://localhost:63342/markdownPreview/651830898//Users/josediaz/Projects/JoeDayz/ClojureSaveme/articles align="center")

En proyectos reales, `reduce` se usa para:

*   sumar ventas
    
*   calcular totales
    
*   crear resúmenes por cliente
    
*   acumular contadores
    
*   generar reportes
    

Por ejemplo:

```plaintext
(defn total-sales  [orders]
  (reduce+ (map:totalorders)))
```

Aquí primero transformamos cada pedido a su total con `map`, y luego reducimos esa colección con `+`.

## **5) Trabajar con maps y datos de negocio**

Los maps son probablemente la estructura más importante cuando modelamos información del negocio. Los usuarios, productos, pedidos y clientes se representan muy bien como maps.

```plaintext
(defn describe-user  [{:keys [nameageemail]}]
  (strname" tiene "age" años y su email es "email))
```

![](http://localhost:63342/markdownPreview/651830898//Users/josediaz/Projects/JoeDayz/ClojureSaveme/articles align="center")

Uso:

```plaintext
(describe-user {:name"Ana":age30:email"ana@example.com"})
;; => "Ana tiene 30 años y su email es ana@example.com"
```

![](http://localhost:63342/markdownPreview/651830898//Users/josediaz/Projects/JoeDayz/ClojureSaveme/articles align="center")

Con esto vemos algo muy útil: no escribimos mucho código para acceder a los datos, y el programa se vuelve mucho más legible.

También es común filtrar registros por una propiedad:

```plaintext
(defn active-users  [users]
  (filter:activeusers))
```

Cuando representas entidades como maps, te resulta mucho más fácil crear lógica de negocio clara y expresiva.

## **6) Recursión y cómo pensar en flujo de datos**

Aunque Clojure ofrece herramientas muy poderosas para iterar, la recursión sigue siendo una pieza clave para entender cómo funciona la lógica funcional.

```java
(defnsum-recursive  [numbers]
  (if (empty?numbers)
0    (+ (firstnumbers)
       (sum-recursive (restnumbers)))))
```

![](http://localhost:63342/markdownPreview/651830898//Users/josediaz/Projects/JoeDayz/ClojureSaveme/articles align="center")

La idea es simple:

1.  revisamos el primer elemento
    
2.  tomamos el resto de la colección
    
3.  repetimos hasta llegar al caso base
    

Cuando la colección está vacía, la recursión termina.

Este tipo de ejemplo ayuda a internalizar la forma en que Clojure trata los datos: como flujo que se va consumiendo paso a paso, sin depender tanto de un estado mutable.

## **7) Pipelines de transformación**

Una de las cosas más valiosas en Clojure es saber encadenar funciones para formar un pipeline claro.

```java
(defnexpensive-items  [products]
  (->>products       (filter #(> (:price%) 100))
       (map:name)))
```

![](http://localhost:63342/markdownPreview/651830898//Users/josediaz/Projects/JoeDayz/ClojureSaveme/articles align="center")

Esto significa:

1.  tomar la colección de productos
    
2.  filtrar solo los caros
    
3.  mapear solo sus nombres
    

Eso es exactamente la mentalidad de Clojure: describir el flujo del dato de una manera muy legible y muy expresiva.

## **8) Por qué esta semana importa tanto**

La semana 2 no trata solo de aprender funciones aisladas. Se trata de desarrollar una manera de pensar:

*   qué datos tengo
    
*   qué quiero transformar
    
*   qué condición necesito aplicar
    
*   qué resultado final necesito obtener
    

Esto es lo que hace que Clojure sea tan potente en proyectos reales.

Cuando entiendes `map`, `filter` y `reduce`, ya puedes:

*   sumar ventas
    
*   filtrar clientes activos
    
*   calcular promociones
    
*   generar reportes
    
*   transformar data de una API
    
*   normalizar información
    
*   preparar estructuras que luego usen otras partes del sistema
    

## **9) El siguiente paso**

Esta semana nos pone en un nivel mucho más útil para el desarrollo real. Ya no solo estamos escribiendo funciones pequeñas; estamos manipulando datos con intención y claridad.

La clave es que cada una de estas herramientas no se usa de forma aislada. Se combinan. Se encadenan. Y eso es lo que hace que el código en Clojure sea tan elegante.

En la siguiente etapa, seguiremos avanzando hacia la organización de proyectos, pruebas y modelado de dominio, pero la base que aprendimos en esta semana será esencial para todo lo que venga después.

Si ya estás practicando con `map`, `filter`, `reduce` y recursión, entonces ya estás empezando a pensar como desarrollador funcional. Y esa es la parte más valiosa del aprendizaje.

Enjoy!

Joe
