En programación, el concepto de la programación pura es aquella función que no cause efectos secundarios en el programa, cuyas funciones estén aisladas del resto del programa y no afecten a nada más que a lo que se le pide que haga.
### Un ejemplo de una "Función Impura":
```SHELL
contador=0 # Esto es un estado global
incrementar() {
#Efecto secundario: Se esta modificando una variable externa
sed 's/^[[:space:]]*//;s/[[:space:]]*$//' <<< "$input"
# Sed modifica streams, pero no toca el sistema, por ende, es válido.
# Es válido porque opera sobre datos y no modifica el sistema.
# En Bash, un comando externo sigue siendo "puro" mientras:
# - "No escriba en ficheros"
# - "No cambie el entorno"
# - "No tenga efectos secundarios"
# Usar comandos externos != impuro
}
texto_sucio=" Hola Mundo "
texto_limpio=$(trim_string "$texto_sucio")
echo "'$texto_sucio' -> '$texto_limpio'"
```
Aquí una función que limpia un string (quita espacios extra). Nota cómo no toca ningún archivo ni variable externa.
---
# El problema de BASH:
Es posible aplicar funciones puras a bash, pero el problema es que bash está pensado para tener efectos secundarios, como la modificación de ficheros y directorios (I/O). Así que es imposible tener un script de bash que tenga solo funciones puras, a no ser que su propósito no sea modificar ningún fichero ni directorio. Es decir, si tienes una función que se llama `crear_carpeta_local()`, ten por seguro de que será una función impura.
En Bash, es muy fácil romper la pureza, porque está orientado a efectos secundarios.
El motivo:
- Usa subshells
- Depende del entorno
- Depende del estado del sistema
- Incluso `echo`, en algunos casos mal utilizados, puede dar impureza al código por dar un valor que la función base no debe devolver. `echo` es aceptable en funciones puras siempre que imprima **únicamente** el valor que la función devuelve. Cualquier salida extra rompe la pureza.
>*Una "Función Pura" es solo un modelo conceptual: Una función que **se comporta como pura**, aunque en la práctica nunca es 100% pura.*
Es innecesario e incluso contraproducente intentar que *todo* sea puro en Bash. Hay que aplicar pureza **solo a funciones que procesan datos**.
---
# Reglas de purificación
Esto empieza a sonar como culto religioso.
Si quieres hacer funciones puras en bash, asegúrate de seguir estas reglas:
1. Usa siempre `local`.
Por defecto, todas las variables son globales. Si defines `i=1` dentro de una función, estás cambiando `i` en todo el script.
- **Regla**: Declara cada variable interna con local (o `declare -n` para referencias).
2.**Entradas solo por argumentos (`$1`, `$2`...)**
Nunca, NUNCA leas una variable global dentro de una función.
Si la función necesita un dato, pásalo como parámetro.
- *Mal*: `echo $USUARIO_GLOBAL`
- *Bien*: `local usuario=$1`
3.**Salidas por `stdout` (echo/printf)**
No asignes el resultado a una variable global. Imprímelo. Quien llame a la función va a capturar ese valor usando *command substitution* `var=$(mi_funcion).
- *Nota*: Usa `return` solo para indicar éxito (0) o error (no-0), no para devolver data.
4.**No escribas en stdout si la función se usa como "función pura interna"**.
Me explico; Si la función forma parte de un pipeline complejo, imprimir cosas rompe la composición.
Ejemplo de lo que NO se debe hacer:
```Shell
sumar() {
echo "$(( $1 + $2 ))"
echo "Suma completada" # Esto lo caga todo.
}
```
El problema no es imprimir como tal.
El problema es imprimir *cualquier cosa que no sea el valor* que la función debe devolver.
Es decir:
- **Pura**: Imprime SOLO el resultado.
- **Impura**: Imprime logs, mensajes, basura, colores, etc.
---
# El porqué de todo esto
Tal vez pienses que es más trabajo, pero los beneficios son enormes:
1.**La depuración es más sencilla**: Si algo, por alguna razón, falla, sabes que el error está *dentro* de ella o en los argumentos que recibió. No tienes que rastrear variables globales por todo el fichero.
2.**Reutilización**: Puedes hacer *copy-paste* de una función pura en otro script y funcionará inmediatamente sin romper nada (en la gran mayoría de casos).
3.**Seguridad**: Evita las colisiones de nombres de variables (el típico error donde dos bucles usan la variable `i` y uno rompe al otro).