# Programación Funcional

La programación funcional es un enfoque de programación en el que se utilizan funciones como la unidad básica de construcción de programas. Evita modificar datos y variables, las funciones toman una entrada y devuelven una salida sin cambiar ningún estado en la aplicación.

En lugar de utilizar bucles y variables que cambian de estado, la programación funcional se basa en la composición de funciones, la recursión y el uso de funciones puras (funciones que siempre devuelven el mismo resultado para los mismos argumentos y no tienen efectos secundarios).

#### Principios Clave de la Programación Funcional:

1. **Funciones Puras**: Una función pura es aquella que, dado el mismo conjunto de argumentos, siempre produce el mismo resultado y no tiene efectos secundarios (como modificar una variable global o alterar el estado de la aplicación).
2. **Inmutabilidad**: En lugar de modificar el estado de las variables, la programación funcional favorece la creación de nuevas variables. Esto elimina muchos errores relacionados con el estado mutable.
3. **Funciones de Orden Superior**: Son funciones que pueden tomar otras funciones como argumentos y/o devolver funciones como resultado. Esto permite construir abstracciones poderosas y reutilizables.
4. **Composición de Funciones**: La capacidad de combinar funciones simples para construir funciones más complejas. Esto se hace a menudo mediante la aplicación de funciones a los resultados de otras funciones.
5. **Recursión**: La recursión se utiliza en lugar de los bucles tradicionales. En muchos lenguajes funcionales, la recursión es optimizada de manera que no cause desbordamiento de pila (tail call optimization).
6. **Transparencia Referencial**: Una expresión es transparentemente referencial si puede ser reemplazada por su valor sin cambiar el comportamiento del programa. Esto es una consecuencia de la pureza de las funciones.

#### Ejemplo en JavaScript

```javascript
// Función pura que suma dos números
const add = (x, y) => x + y;

// Uso de funciones de orden superior: map aplica una función a cada elemento de una lista
const squaredNumbers = (xs) => xs.map(x => x * x);

// Recursión: cálculo del factorial de un número
const factorial = (n) => {    
    if (n === 0) return 1;    
    return n * factorial(n - 1);
};
```

#### Ventajas de la Programación Funcional

* **Facilidad para Razonar**: El código funcional es más fácil de razonar debido a la ausencia de efectos secundarios.
* **Paralelismo y Concurrencia**: Debido a la inmutabilidad, es más fácil escribir programas concurrentes y paralelos.
* **Reutilización y Composición**: Las funciones de orden superior y la composición de funciones permiten reutilizar y combinar código de manera más efectiva.

#### Desventajas de la Programación Funcional

* **Curva de Aprendizaje**: Puede ser difícil de aprender para aquellos acostumbrados a paradigmas imperativos.
* **Rendimiento**: En algunos casos, la programación funcional puede ser menos eficiente en términos de uso de memoria y velocidad de ejecución debido a la creación constante de nuevos valores.

En resumen, la programación funcional es un enfoque poderoso y elegante para escribir software que enfatiza la inmutabilidad y las funciones puras, lo que puede llevar a un código más claro, conciso y fácil de mantener.

Un ejemplo de la programación funcional es Redux que promueve el uso de funciones puras y valores inmutables.
