Así, si quisieramos la sumatoria de los valores en un arreglo numérico el código (en python) seria:
suma = 0
for x in arreglo :
suma += x
Para elevar al cuadrado los componentes de un arreglo, la solución que implementaría un programador de C escribiendo python seria:
for i in len(arreglo) :
arreglo[i] = arreglo[i]**2
(python tienen una forma mas elegante de lograrlo, pero es precisamente una forma "prestada" de lenguajes con paradigmas diferentes al imperativo).
Estos códigos son representativos de las soluciones imperativas: crear un bucle que recorra el arreglo, operando sobre cada elemento para generar el resultado deseado. Un programador de C o Java con algunos años de experiencia habrá escrito lineas semejantes a esas un millar de veces. El problema esta en que precisamente la tarea es tan común que forma un patrón ideal para ser resumido.
Ahora, como podría aislarse esa solución en un lenguaje como C o Java, de manera que el programador solo tuviera que escribir la parte del problema que cambia (el suma +=x o el arreglo[i] = arreglo[i]**2)? Dado que la estructura semántica del C y el java están fijadas y no lo permiten directamente, la única posibilidad seria por medio de una librería. La librería implementaría la parte común (el bucle) y recibiría como parámetro un elemento (un objeto en Java o un apuntador a una función en C) que contenga el pedazo de programa que varía.
Y he allí el problema. Declarar una función en C es mas trabajo que escribir el bucle directamente. Definir una clase en Java que implemente el comportamiento deseado, instanciarla y pasar el objeto a la librería no es una opción: es una penitencia.
La mayoría de los lenguajes funcionales por otra parte permiten la creación de funciones con un costo mínimo para el programador, razón por la cual hacer una librería con los tipos mas comunes de bucles no solo es viable, sino la forma natural de proceder.
El primer caso mostrado, la suma de los valores en un arreglo, es de hecho un caso particular de un tipo de bucles llamado fold (también llamado reduce). Este caso se caracteriza por dos elementos: un valor a ser devuelto en caso que el arreglo sea de longitud cero, y una función que tome dos valores y devuelve uno, la cual es usada para "reducir" el arreglo. En nuestro caso, el valor a ser devuelto en caso que el arreglo este vació es cero y la función que reduce el arreglo es la suma.
Así, expresar ese bucle en python de forma funcional seria
reduce(real.__add__, arreglo, 0.0)
En Haskell, uno de los lenguajes mas elegantes, seria
foldr (+) 0.0 arreglo
En ambos casos el significado es el mismo: si el arreglo esta vació, devuelve 0.0, sino suma sus elementos. Si bien este programa puede resultar de mas difícil lectura (sobre todo debido a la costumbre imperativa), también ofrece algunas ventajas:
- Es mas conciso
- No usa variables temporales
- Puede ser manipulado programaticamente
No comments:
Post a Comment