13. Lazy Sequences

¿Recuerdas cuando en el capítulo del REPL sumamos los 10 primeros millones de números y Clojure no se inmutó? El secreto se llama evaluación perezosa. Las secuencias perezosas no calculan sus valores hasta que alguien los necesita. Es como un escudero que no prepara la comida hasta que el caballero tiene hambre. ¿Para qué cocinar un banquete si solo quieres una manzana?

Muchas funciones que ya conoces (map, filter, remove, range, take) devuelven secuencias perezosas. Esto permite trabajar con secuencias infinitas sin desbordar la memoria.

(take 10 (range))
;; (0 1 2 3 4 5 6 7 8 9)

(range) sin argumentos genera una secuencia infinita. take solo calcula los 10 primeros.

Generadores

(take 5 (repeat "ha"))
;; ("ha" "ha" "ha" "ha" "ha")

(take 10 (iterate inc 1))
;; (1 2 3 4 5 6 7 8 9 10)

(take 10 (cycle [:a :b :c]))
;; (:a :b :c :a :b :c :a :b :c :a)

Composición

Aquí es donde la magia se desborda. Al combinar funciones perezosas, cada eslabón de la cadena solo trabaja cuando el siguiente se lo pide.

(take 5 (filter even? (range)))
;; (0 2 4 6 8)

Solo se calculan los 5 primeros pares, no la secuencia infinita.

Forzar la evaluación

  • doall: evalúa toda la secuencia y retiene los resultados.

  • dorun: evalúa toda la secuencia, descarta los resultados (útil para efectos secundarios).

(doall (map inc [1 2 3 4]))
;; (2 3 4 5)

Resumen

  • Las secuencias perezosas calculan valores solo cuando se necesitan.

  • repeat, iterate, cycle y range generan secuencias perezosas.

  • Componer funciones perezosas es eficiente: solo se calcula lo necesario.

  • doall y dorun fuerzan la evaluación cuando hace falta.

Ejercicios

  1. Genera los 20 primeros múltiplos de 7 usando iterate y take.

  2. Crea una secuencia infinita de potencias de 2 (1, 2, 4, 8, 16…) y obtén las 10 primeras.

Este trabajo está bajo una licencia Attribution-NonCommercial-NoDerivatives 4.0 International.

¿Me invitas a un café?

Visitantes en tiempo real

Estás solo: 🐱