18 octubre 2012

Programación funcional

Hola a tod@s,
después de mucho tiempo sin escribir nada en el bloc voy a retomar, en la medida de lo posible, la escritura regular de artículos. Últimamente me ha entrado el gusanillo de aprender de que va esto de la programación funcional y para ello he estado haciendo mis primeros pinitos con Scala aprovechando el curso Functional Programming Principles in Scala que imparte el mismísimo Martin Odersky en la plataforma on-line Coursera.
Con el objetivo de afianzar los conocimientos adquiridos en el curso y a modo de recordatorio personal voy a escribir una serie de artículos breves con los conceptos básicos de programación funcional.
Para que no perdáis el tiempo, os comento lo que creo que debéis hacer, en función de vuestro background, si os topáis con un artículo de esta serie:
  • Alguien que no tenga demasiada experiencia en programación funcional pero le interese el tema: no os toméis lo que digo en los artículos “a pies juntillas”, contrastadlo y corregidme las partes que creáis que no son correctas. Tomaros los artículos como un primera toma de contacto y, si os interesa el tema, leed artículos de gente con más experiencia y contrastad lo que se comenta. Después de eso, todo el feedback que podáis aportar a los artículos en forma de comentarios será muy bienvenido. Ah! y apuntaros al curso de programación funcional.
  • Alguien experto en programación funcional: tenéis dos opciones, o bien obviarlos por completo ya que seguro que no os aportarán nada nuevo o bien leer los post con detalle y comentar los posibles errores e inexactitudes que encontréis. Lógicamente os animo a hacer lo segundo!
  • Alguien al quien no le interesa la programación funcional: Obviad los artículos por completo Sonrisa
En esta serie de artículos breves voy a intentar plasmar las dificultades y sorpresas que me encuentro en el proceso de aprendizaje del paradigma de programación funcional (FP) desde la perspectiva de un desarrollador de software OO, que es el paradigma con el que me desenvuelvo bien. El objetivo último es asentar los conocimientos adquiridos sobre programación funcional y hacerlo estableciendo paralelismos con la programación OO.
Para ello voy a resumir los conceptos mas relevantes del curso e intentaré plantear y resolver algunos problemas sencillos de varias formas, usando paradigmas OO, funcionales e híbridos con el propósito de hacer comparaciones y analizar las ventajas y desventajas de cada una de ellas. Para los ejemplos usaré indistintamente Java, C#, JavaScript y Scala.
En el curso se usa Scala como lenguaje de programación pero el verdadero objetivo del curso no es aprender Scala si no aprender a programar siguiendo un paradigma funcional. Pensar la resolución de un problema mediante un paradigma funcional te hace replantear tus esquemas mentales y…, cuesta, para que engañarnos, cuesta mucho. La primera sensación, en la resolución del primer Homework del curso, fue: ¿por donde empiezo? La programación funcional es un paradigma bastante diferente al paradigma usado en programación imperativa y te quedas bastante bloqueado inicialmente!
En esta primera entrada voy a poner en contexto la programación funcional y sus principios básicos, resumiendo partes de la primera semana del curso. También intentaré responder a LA PREGUNTA en mayúsculas, ¿POR QUÉ programación funcional ahora?.

¿Qué es la programación funcional?

Los principales paradigmas de programación existentes son:
  • Programación funcional (FP)
  • Programación imperativa
  • Programación lógica
el paradigma OO lo podemos considerar como un paradigma ortogonal a los tres anteriores ya que se puede combinar con cualquiera de los tres paradigmas anteriores (lo que estamos mas acostumbrados a hacer es a combinar programación imperativa con OO pero veremos que también es posible combinar elementos de FP con elementos OO)
Las ideas principales en las que se basa la programación imperativa son:
  • Modificación de variables mutables usando asignaciones
  • Uso masivo de estructuras de control: bucles, if-then-else, etc…
Las ideas principales en las que se basa la programación funcional son:
  • Se basa en definir teorías para operadores expresadas como funciones
  • Evita, en la medida de lo posible, el uso de mutaciones usando asignaciones (en sentido estricto las prohíbe)
  • Evita, en la medida de lo posible, el uso de estructuras de control (en sentido estricto las prohíbe)
  • Se basa en la abstracción y composición de funciones.
La programación funcional se basa en teorías matemáticas como el lambda-calculus y estas teorías no se pueden aplicar a la programación imperativa ya que su principio básico (la modificación de variables mutables) NO tiene cabida en las teorías matemáticas. Es decir, cuando introducimos la mutación de variables ya no podemos aplicar las leyes por las que se rigen las teorías matemáticas ya que en ellas no está permitida la mutación.
Mi primera sorpresa… ¿en programación funcional no se pude modificar una variable y se deben evitar las estructuras de control? Pues en sentido estricto SI… Es especialmente interesante ver como en el libro Structure and Interpretation of Computer Programs , uno de los libros de clásicos, de cabecera, de la introducción a la programación en los cursos del MIT, no se habla de mutación de variables hasta el capítulo 3…
Pero, ¿porqué es importante usar los conceptos de las teorías matemáticas un un paradigma de programación? Según Odersky sin el uso de teorías matemáticas un paradigma de programación tiene problemas para implementar conceptos de alto nivel y, por tanto, tiene problemas de escalabilidad conceptual. El uso de teorías proporciona formas muy potentes de abstraer y componer funciones y proporciona una escalabilidad conceptual que nos permite dejar atrás la correspondencia uno a uno entre las instrucciones de un lenguaje imperativo y secuencia de instrucciones para una máquina de Von Neumann.
En este punto, después de la primera toma de contacto con la programación funcional, me asaltó una pregunta realmente importante y su análisis me llevo a pensar que la programación funcional tomará mucha relevancia y será clave en el desarrollo de software: ¿Porqué programación funcional?

¿Porqué programación  funcional?

Si hacemos un poco de historia, la programación funcional lleva con nosotros mas de 50 años. Apareció con Lisp a finales de los 50 y, hasta la actualidad, era un paradigma de programación que se usaba casi exclusivamente en el ámbito académico y en algunas aplicaciones de Inteligencia Artificial, su presencia en el mundo de la industria era prácticamente nula. ¿Qué hace pues que ahora parezca que la programación funcional se abre hueco con fuerza en el mundo de la industria?
Para intentar responder a esta pregunta veamos primero las ventajas que nos ofrece la programación funcional. Cuando hablamos de las ventajas de la programación funcional respecto a la programación más clásica aparecen siempre estos argumentos:
  • Alto nivel de abstracción: La programación funcional proporciona un nivel de abstracción mucho más alto.
  • Productividad: Un programa funcional tiene muchas menos líneas de código => menos bugs => menos mantenimiento. En este sentido se argumenta que la programación funcional puede llegar a ser un orden de magnitud más
Si bien los argumentos anteriores son importantes, creo que el porqué de la programación funcional en nuestros días tiene mucho mas que ver con estos dos hechos que con las ventajas comentadas anteriormente:
  • Actualmente las aplicaciones se ejecutan en ordenadores multicore con una capacidad de procesamiento y de paralelización muy grande.
  • Cada vez mas se tiende a desplegar las aplicaciones usando Cloud Computing donde, por temas de escalabilidad, es muy importante que las aplicaciones sean altamente paralelizables.
Estamos pues de acuerdo que la paralelización es un concepto clave para las aplicaciones actuales pero, ¿tiene esto algo que ver con la programación funcional? pues parece que si, y mucho!
En este punto os aconsejo que vais el vídeo O'Reilly OSCON Java 2011: Martin Odersky, "Working Hard to Keep It Simple" que fue el que cambió mi percepción sobre la programación funcional hacia algo mas mundano y realmente necesario. En el vídeo Odersky argumenta que las aplicaciones de hoy son altamente concurrentes por definición y deben ser altamente paralelizables y que esto se puede conseguir más fácilmente siguiendo un paradigma funcional ya que se basa en la inmutabilidad de las variables (bien, realmente promulga el uso de Scala, que estrictamente es un lenguaje híbrido OO-funcional, pero creo que los argumentos que expone se pueden extrapolar a cualquier lenguaje que admita un paradigma funcional).
Del vídeo también encuentro interesante también la asociación que hace entre “programación imperativa = focalización en el tiempo” y “programación funcional => focalización en el espacio” y como lo enlaza con la dificultad de gestionar la concurrencia.
Fijaros que uno de los principios básicos de la pro
Etiquetas de Technorati: ,
gramación funcional es la inmutabilidad de las variables, esto implica que la ejecución del código no tiene “side-effects”, es decir, la ejecución de una función con los mismos argumentos proporciona siempre el mismo resultado => el orden de ejecución de un programa funcional es irrelevante. Ummmm, un código con estas características parece que será altamente parelelizable ¿no?
Para mi esta es la motivación real del auge hoy en día de la programación funcional, ya que soluciona un problema tangible y muy actual como es la paralelización y además lo hace de la mano de un conjunto de teorías muy sólidas (basadas en teorías matemática) y un nivel de abstracción superior a los lenguajes imperativos.

Conclusiones

De mi  primera toma de contacto con la programación funcional me quedo con lo siguiente:
  • La programación funcional se basa en un paradigma muy diferente al que he usado hasta ahora y abre nuevas formas de plantear los problemas mucho mas naturales.
  • La clave del auge actual de la programación funcional es que la escalabilidad y la parelelización son imprescindibles en las aplicaciones actuales y paralelizar con mutación de estado es muy complejo.
  • Quiero aprender mucho más sobre programación funcional!!!