¿Qué es la programación funcional?
Si eres programador es muy probable que en algún momento hayas leído o escuchado hablar sobre la programación funcional como algo que trae grandes beneficios al desarrollo de software.
La programación funcional tiene su origen en el cálculo lambda de Alonzo Church y en los sistemas formales, este fundamento fuertemente teórico y cercano a la matemática puede hacer complicado entender en qué consiste.
La mayoría de problemas en un programa de software provienen de la incapacidad de los desarrolladores para predecir o tener en cuenta todos los posibles estados en los que puede ejecutarse una determinada pieza de código.
El paradigma de programación funcional pretende eliminar los cambios de estado, para ello se basa principalmente en la composición de funciones, la transparencia referencial y las funciones puras.
Composición de funciones.
En un lenguaje de programación orientado a objetos como puede ser Ruby los objetos son el elemento básico de abstracción. Los objetos encapsulan estructuras de datos y funciones que modifican estas estructuras. Los programas se construyen mediante una composición de diferentes tipos de objetos interactuando entre sí.
El paradigma funcional separa las estructuras de datos y las funciones que operan sobre ellas. Los programas se construyen mediante la composición de funciones, de manera que una función realiza su trabajo llamando a otras funciones cada vez más simples hasta alcanzar las primitivas del lenguaje.
Las funciones son un elemento de primer orden en el lenguaje, al igual que pueden ser los números o las cadenas de texto. Esto permite, entre otras cosas, el almacenamiento de funciones en una lista o en cualquier otra estructura de datos.
Puesto que las funciones son un elemento de primer orden, también pueden recibir otras funciones como parámetros o devolveras como resultado de su ejecución. Este tipo de funciones que reciben o devuelven otras funciones se llaman funciones de orden superior y son el elemento básico de composición y reutilización de código en el paradigma funcional.
Transparencia referencial y funciones puras.
El gran pilar del paradigma funcional es la transparencia referencial. En la teoría de lenguajes de programación el concepto de transparencia referencial indica que una expresión puede ser sustituida directamente por su valor sin que esto afecte a la ejecución del programa. El ejemplo más claro de expresiones referencialmente transparentes son todas las funciones matemáticas.
A simple vista la implicación más directa de la transparencia referencial es que la evaluación de una expresión depende única y exclusivamente de sus parámetros de entrada. Entre otras cosas esto significa que invocar una función con los mismos argumentos siempre produce el mismo resultado.
El otro gran efecto de la transparencia referencial es la ausencia de efectos colaterales, una función sólo retorna un valor y no produce cambios de estado.
Por ejemplo, en un lenguaje de programación orientado a objetos podemos tener un objeto de tipo lista que contiene varios elementos, para añadir un nuevo elemento modificamos la lista de manera que contenga el nuevo elemento. Esta modificación de la lista original es un efecto colateral.
En un lenguaje de programación funcional la misma función devolvería una nueva lista incluyendo todos los elementos de la original y el nuevo elemento que queremos añadir. Crear una nueva lista equivalente en lugar de modificar la original hace que nuestra función no tenga efectos colaterales. Este tipo de funciones que no tienen efectos colaterales reciben el nombre de funciones puras.
En resumen.
El paradigma de programación funcional tiene como objetivo evitar los cambios de estado y hacer explícitas las transformaciones de datos. Para ello se basa en tres principios clave:
- Las funciones son el elemento básico de abstracción y reutilización de código. Los programas se construyen mediante una composición de funciones.
- Las funciones son un elemento de primer orden en el lenguaje. Pueden guardarse en estructuras de datos, pasarse como argumentos y devolverse desde otras funciones.
- El resultado de evaluar una expresión depende única y exclusivamente de sus parámetros de entrada. Ante una misma entrada siempre obtenemos el mismo resultado.
¿Dónde puedo investigar más?
En mi opinión, la mejor explicación sobre la programación funcional y sus conceptos está en el paper Why Functional Programming Matters, John Hughes, 1984. La entrada de Wikipedia sobre la programación funcional es también un buen punto de partida (son especialmente interesantes las secciones de Historia y Comparación con la Programación Imperativa). Para profundizar más, es muy interesante el clásico Structure and Interpretation of Computer Programs, Abelson y Sussman, 1985.
En cuanto a blogs, no puedo dejar de recomendar el post 16 Months of Functional Programming, Vasily Vasinov, así como el genial In-depth: Functional programming in C++, John Carmack.
Por último, una muy buena introducción práctica es el curso Principios de Programación Funcional en Scala, Coursera que imparte Martin Odersky (creador del lenguaje de programación Scala) y en el que te puedes matricular completamente gratis.