La Programación Funcional (Functional Programming)es un paradigma de programación declarativa (decir qué queremos, pero no cómo hacerlo) basado en el uso de funciones matemáticas donde:
- Estaremos trabajando principalmente con funciones (el elemento principal para construir programas), evitaremos los datos mutables, así como el hecho de compartir estados entre funciones.
- Y donde el valor generado por una función depende exclusivamente de los argumentos alimentados a la función.
- Las funciones serán tratadas como ciudadanos de primera clase y podrán ser asignadas a variables además podrán ser utilizadas como entrada y salida de otras funciones.
- Además, evitamos a toda costa los efectos secundarios que alteren el estado del programa u otros programas.
- Ejemplos de lenguajes que soportan este paradigma son Haskell, Elixir, Erlang , Scala, y Clojure.
Características principales:
- Funciones puras: Las funciones siempre producen el mismo resultado para los mismos argumentos y no tienen efectos colaterales (no modifican variables globales ni realizan I/O directamente).
- Inmutabilidad: Los datos no se pueden modificar una vez creados. En lugar de cambiar valores, se crean nuevos valores.
- Funciones de orden superior: Las funciones pueden aceptar otras funciones como argumentos o devolver funciones.
- Composición de funciones: Las funciones se pueden combinar para crear otras más complejas, facilitando la reutilización de código.
- Evaluación perezosa: Las expresiones no se evalúan hasta que su resultado es necesario, optimizando el rendimiento en muchos casos.
Ventajas:
- Código más predecible y fácil de razonar gracias a la ausencia de efectos colaterales.
- Facilidad para la concurrencia y el paralelismo, ya que no hay variables mutables que puedan causar conflictos.
Algunos conceptos clave de la Programación Funcional
- Funciones puras: Funciones que siempre producen el mismo resultado para los mismos argumentos.
- Inmutabilidad: Los valores no pueden ser modificados una vez creados.
- Currificación: Funciones que pueden ser llamadas con menos argumentos de los que requieren originalmente.
- Composición de funciones: Encadenar funciones mediante el operador (.).
- Pattern matching: Hacer coincidir patrones en listas, tuplas, y otros datos estructurados.
- Guards y condicionales: Usar guards para control de flujo condicional.
- Recursión: La forma principal de control de iteraciones.
Ejemplo 1. Crear una función pura que nos sume dos números enteros. Este ejemplo lo haremos en Haskell.
suma.hs
suma :: Int -> Int -> Int suma x y = x + y main :: IO() main = print (suma 8 3)
Como se puede ver, iniciamos con la delaración de tipos (Int). Definimos la función (suma) y en la d¿función principal (main) asignamos dos valores por default (8 y 3), lo cual nos dará como resultado 11.
Si solo queremos ejecutar el programa, abrimos una terminal y tecleamos lo siguiente:
runghc suma.hs
Si queremos compilar y crear un ejecutable, entonces:
ghc -o suma.exe suma.hs
Como la definición de una Función Pura indica, el resultado será el mismo cuando los argumentos son los mismos. Si invertimos el lugar del los valores (8, 3 por 3,8) el resultado seguirá siendo el mismo.
Aprender programación funcional se ha vuelto una "moda" que ya no solo implica el ámbito académico. Puesto que ya son muchos proyectos como la I.A. o Aprendizaje Automático que cada vez más requieren desarrolladores que dominen los principios de la matemática y, por ende, la programación funcional.
Enlaces:
https://codemonkeyjunior.blogspot.com/search?q=erlanghttps://codemonkeyjunior.blogspot.com/search?q=elixir
https://emanuelpeg.blogspot.com/search?q=haskell