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?
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.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.
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.”
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.
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 .
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.