30 noviembre 2012

La programación funcional y los patrones de diseño

Hola a tod@s,
como desarrollador de software creo que todos tenemos que hacer nuestro trabajo lo mejor posible. Una de las herramientas que me han ayudado más en el desarrollo OO ha sido la aplicación de patrones de diseño para solventar problemáticas concretas que se dan de forma recurrente en el desarrollo de sistemas software
“Un patrón de diseño define una posible solución correcta para un problema de diseño dentro de un contexto dado, describiendo las cualidades invariantes de todas las soluciones”
Cómo parte de mi inmersión inicial en el paradigma de programación funcional me pregunte lo siguiente:
  • ¿Tiene sentido hablar de patrones de diseño en el entorno de la programación funcional?
  • ¿Los patrones de diseño clásicos que aplicamos en programación OO (por ejemplo, los patrones GoF) son igualmente válidos para programación funcional?
  • ¿Existe un catálogo de patrones de patrones de diseño específico para programación funcional o se aplican los mismos que aplicamos en programación OO?
Estaba en estas tesituras cuando tropecé con la siguiente reflexión en StackOverflow: Does Functional Programming Replace GoF Design Patterns?, en este hilo de discusión aparecen varias ideas y reflexiones muy interesantes sobre la relación entre la programación funcional y los patrones de diseño. Os recomiendo encarecidamente que lo leáis con atención porqué la discusión es sumamente interesante y algunas de las ideas/opiniones son, cuando menos, sorprendentes para los que venimos del paradigma OO.
En este artículo intentaré enumerar algunas de ellas y, des de la mas absoluta modestia de un neófito en el excitante mundo de la programación funcional, daré mi opinión al respecto.

Patrones de diseño en programación funcional

La discusión inicial del hilo arranca del siguiente parágrafo del artículo Functional Programming For The Rest of Us (otro “must read”!):
“Most people I've met have read the Design Patterns book by the Gang of Four. Any self respecting programmer will tell you that the book is language agnostic and the patterns apply to software engineering in general, regardless of which language you use. This is a noble claim. Unfortunately it is far removed from the truth.
Functional languages are extremely expressive. In a functional language one does not need design patterns because the language is likely so high level, you end up programming in concepts that eliminate design patterns all together.”
el autor argumenta pues que en programación funcional, debido a que se trata de un paradigma en el que se desarrolla y trabaja en un nivel de abstracción más alto que en el paradigma OO, NO tiene sentido aplicar patrones de diseño porqué las capacidades de los lenguajes de programación funcionales los hacen innecesarios.
En este sentido me sorprendió especialmente, que se definiera un patrón de diseño como un “parche” que soluciona un problema o una deficiencia del paradigma o, si somos más específicos, del lenguaje.
Los patrones de diseño evolucionan junto a las capacidades y niveles de abstracción que proporcionan los paradigmas y lenguajes de programación para los que se definen. Un el hilo se pone un ejemplo bastante tonto pero que expresa esta idea:
Supongamos que los lenguajes de programación no proporcionaran una construcción para iterar sobre una colección de elementos, ¿se consideraría una solución que definiera como iterar sobre un conjunto de elementos de una colección un patrón de diseño? Pues posiblemente si, ya que se estaría dando una solución correcta a un problema dado… pero, ¿tiene sentido considerar actualmente esto como un patrón de diseño? No, ya que esta es una capacidad existente en todos los lenguajes de programación y, por tanto, el patrón proporcionaría una solución a un problema inexistente.
Pienso que el nivel de abstracción superior de los lenguajes funcionales hace que, lo que en otros paradigmas era un problema recurrente (i, por tanto, requería un patrón de diseño que proporcionara una solución) simplemente no suponga un problema por qué ya se dispone de una abstracción “de serie” que la soluciona.
¿Quiere decir esto que en programación funcional no tiene sentido hablar de patrones de diseño? para mi no, simplemente los patrones de diseño en programación funcional serán diferentes a los patrones de diseño de otros paradigmas (por ejemplo, los patrones de diseño para programación OO que se define en GoF).

Patrones GoF y la programación funcional

En el hilo se discute bastante sobre si tienen sentido en programación funcional los patrones de diseño definidos en el libro Design Patterns: Elements of Reusable Object-Oriented Software.
Bajo mi punto de vista, la respuesta la tenemos precisamente en el título del libro, concretamente en esta parte: “… of Reusable Object-Oriented Software” => el libro de cabecera sobre patrones de diseño define 23 patrones de diseño bajo un paradigma OO NO bajo un paradigma funcional, lo primordial es que los patrones de diseño lo son para un determinado paradigma, es decir, no son independientes del paradigma bajo el que se aplican. Muchas veces incluso, aunque se promulgue lo contrario, tampoco son independientes del lenguaje de programación que se esté usando.
Sirva como ejemplo el patrón Singleton en un lenguaje “medio OO-medio funcional” como Scala, en el no tiene sentido aplicar este patrón de la forma en que lo describe GoF simplemente porqué el lenguaje tiene soporte directo para ello.
Lo que en programación OO es un problema recurrente que requería un patrón de diseño para su resolución,  en programación funcional simplemente no es un problema, o el problema resulta tan trivial que no requiere la definición de un patrón de diseño para su resolución. El mayor nivel de abstracción y los conceptos presentes en programación funcional como: High Order Functions, Currying, Closures, Data Types algebraicos, Pattern Matching, etc… proporcionan soluciones “de serie” o “embeded” para la mayoría de patrones que describe GoF.
Con los patrones tradicionales en programación funcional pueden pasar tres cosas:
    • el patrón desaparece debido a que el lenguaje ya proporciona esa funcionalidad.
    • el patrón sigue existiendo pero la solución es radicalmente diferente.
    • el patrón sigue existiendo pero la solución se implementa usando nuevas capacidades del lenguaje o del paradigma.
Parece claro pues que NO se requieren los mismos patrones en programación OO que en programación funcional y no es una buena idea intentar aplicar los patrones OO dentro de un paradigma funcional. De hecho la manera de diseñar software en programación funcional es muy diferente a la que estamos acostumbrados en OO, esto hace que los problemas a resolver muchas veces tengan poco a ver con los problemas a los que nos enfrentamos en OO.
Si estáis interesados en saber como se resuelve en programación funcional la problemática que describen los patrones GoF en el enlace Design Patterns in Haskell hay una interesante correspondencia entre estos patrones y su resolución en Haskell y Peter Norvig tiene una presentación con soluciones triviales a 16 de los 23 patrones en lenguajes dinámicos. Hay algunas de estas soluciones que merecen un análisis un poco mas detallado, pero esto lo dejaremos para otras entradas Guio.

Conclusión

Las ideas principales con las que me quedo después de escribir el artículo son:
  • Los patrones de diseño sirven para solucionar problemas existentes, si no hay problema a resolver no tiene sentido hablar de patrón de diseño para resolverlo.
  • La naturaleza de los paradigmas de programación y las capacidades de los lenguajes de programación marcan los patrones de diseño aplicables en cada caso.
  • El mayor nivel de abstracción del paradigma funcional hace que muchos de los problemas que hay en OO no sean problemas y, por tanto, no tenga sentido plantear un patrón de diseño para ellos.
  • En programación funcional se tiende a hablar de reglas o de buenas prácticas para resolver problemas concretos que de patrones de diseño.
  • En programación funcional SI necesitamos patrones de diseño pero son distintos a los que necesitamos en programación OO.
y con la tarea de conocer mucho mas a fondo la programación funcional y los patrones, reglas o buenas prácticas que se aplican en este paradigma.

2 comentarios:

Mon dijo...

Hola

Estoy totalmente de acuerdo con el tema... aunque tengo una duda.

Existen patrones independientes de la orientacion del lenguaje ?

Existen patrones que no son especificos de la naturaleza del lenguaje como por ejemplo un patrón de Observador y Observable ?

O que aún no exiten lenguajes que puedan salvar problemas de integración de ecosistemas de soluciones...

Puede que me equivoque mucho.
Pero pueden existir suprapatrones...que van ligado a conceptos más genericos como a la esencia de la informatica actual sujetas a los principios de Von Newman por ejemplo ?

Mon dijo...

.