[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Programación funcional en Java



Hola a todos,

Casi todos estaremos de acuerdo en que una de las claves para conseguir
que el código sea más fácil de comprender, y por lo tanto más fácil de
depurar, reutilizar e incluso de escribir, es que esté bien
estructurado. En este sentido, algunas de las características propias de
la programación funcional [1] que se encuentran en lenguajes como
Haskell, Erlang o Lisp son especialmente eficaces.

Desgraciadamente, Java es un lenguaje imperativo en el que las funciones
no se consideran objetos de primera clase. Aún así, es posible emplear
algunas construcciones de la programación funcional como "closures" [2]
y funciones de orden superior que nos permiten escribir código Java más
módular (los "closures" son bloques de código que pueden ser manejados
como datos y pasados como un argumentos a una función, mientras que las
funciones de orden superior son capaces de recibir otras funciones como
argumentos o de devolver una función como salida), como describe
Belapurkar en su artículo "Functional programming in the Java language" [3].

Hasta ahora Java no soporta directamente los closures. Los cambios en
Java 5 (tipos genéricos, autoboxing o bucle for mejorado) están
principalmente dirigidos a reducir el exceso de sintaxis innecesaria del
lenguaje, esperemos que en el futuro se añada soporte para este tipo de
elementos.  Lo más parecido en Java son las clases anónimas internas,
pero no llegan a tener la misma potencia y tienen el inconveniente de
que requieren demasiada sintaxis adicional.

Sin embargo, existen diferentes frameworks para programar al "estilo
funcional" en Java. El artículo de Belapurkar se centra en Apache
Commons Functor [4]. Existen otras soluciones y personalmente me gusta
más la aproximación de FunctionalJ [5] por tratarse de un API no
intrusivo que no requiere que el código del proyecto herede/implemente
alguna clase/interfaz del framework.

FunctionalJ facilita la representación de cualquier método de clase o de
instancia como un objeto y su invocación dinámica en tiempo de ejecución
(en realidad es un envoltorio del Reflection API). Esto nos permite
crear funciones de orden superior muy potentes. El propio framework
incluye una clase Functions con algunas de estas funciones de orden
superior que ilustran el manejo de colecciones.

Por ejemplo, el código para filtrar una colección de objetos y quedarse
con aquellos que cumplan una cierta condición que típicamente sería algo
así:

    List keep = new ArrayList();
    for (Iterator iterator = list.iterator(); iterator.hasNext(); ) {
        SomeClass next = (SomeClass) iterator.next();
            if (next.isValid()) {
                keep.add(next);
            }
    }

quedaría reducido a algo así:

    Function f = new InstanceFunction(SomeClass.class, "isValid");
    List keep = Functions.filter(f, list);  

En este caso, la función de orden superior "filter" implementa un
iterador interno (frente a los iteradores externos que tenemos
disponibles en Java) que recibe como argumento una función que aplica
sobre cada uno de los objetos de la colección.

El sitio web de FunctionalJ incluye otros muchos ejemplos interesantes
de aplicación.

Un saludo,
Rafa

[1] http://en.wikipedia.org/wiki/Functional_programming
[2] http://www.martinfowler.com/bliki/Closure.html
[3] http://www-128.ibm.com/developerworks/java/library/j-fp.html
[4] http://jakarta.apache.org/commons/sandbox/functor/
[5] http://functionalj.sourceforge.net/

-- 
Rafael Luque Leiva
Desarrollador de software

Orange Soft - http://www.orange-soft.com
Creando software para las personas

Urbanización Las Castañeras
Arroyo de los Combos, 26 bis
Arroyomolinos, E28939 Madrid
Tel: +34 916 091 075
     +34 605 511 847 (móvil)
Fax: +34 916 091 075

GnuPG Key ID: 0x4B9238A2