Introducción:

Para quienes ya programaron en lenguajes como C, C++, Pascal, y/o Java, y que a lo mejor solo conocian de la existencia de lenguajes dinámicos (mal llamados de script) como JavaScript, Lisp, o Python sin entrar en profundizar, seguramente no conocian o no conocen la palabra Closure.

Que es un Closure?

En el contexto de la programación un closure no es otra cosa que un bloque de código que puede ser pasado como argumento a la llamada de una función y está presente de forma nativa en la mayoría de los lenguajes dinámicos como Lisp, JavaScript, Smalltalk, Ruby, en Python (mediante los lambda).

Veamos un ejemplo en Ruby, JavaScript y Python (mis preferidos).

JavaScript:

var eachArr = function (arr, callback) {
    for (var i = 0; i < arr.length; i++) {
        callback(arr[i]);
     }
 };
eachArr( [1, 2, 3], function( e ) { alert(e); } );

Ruby (Nativo):

[1, 2, 3].each {|e| puts e}

Python (nativo a través de las lambda pero limitado a un bloque de una expresión, no obstante es posible crear closures pasando funciones como argumentos a otras funciones al igual que hicimos en el ejemplo de JavaScript):

def eachArr(arr, l):
    r = [];
    for e in arr:
        r.append(l(e))
    return r
print eachArr([1,2,3], lambda e: e*e)

Donde pueden aplicarse los Closures?:

Supongamos que hemos hecho una aplicación donde tenemos un listado de objetos productos y nos han pedido hacer un servicio para descubrir el listado de productos que pertenecen a una categoría.

En Java 5 que NO incorpora closures hariamos algo como esto:

public List pertecenenA(List l, String categoria) {
    List result = new ArrayList();
    for (Producto p : l) {
        if (p.perteneceA(categoria)) {
            result.add(p);
        }
    }
    return result;
}

En Ruby, sería algo como:

def pertenecenA(productos, categoria)
    return productos.select { |p| p.perteneceA(categoria) }
end

Aquí “select” es un método nativo de las listas en Ruby que acepta un closure y que debe retornar true/false basado en una expresión, en este caso el bloque de código pregunta si p(instancia de Producto, se omiten las definiciones para acortar el post) pertenece a la categoría, si retorna true Ruby automaticamente lo incluye en la sublista. Bien mas sencillo no?

Closures en Java:

Java (hasta la version 6) no incluye closures, sin embargo es posible simularlo usando clases anónimas (particularmente lo uso mucho). Por ejemplo, algo como:

public interface QueryProduct {
    boolean isTrue(Producto p);
}
public List query(List l, QueryProduct ask) {
    List result = new ArrayList();
    for (final Producto p : l) {
        if (ask.isTrue(p)) {
            result.add(p);
        }
    }
    return result;
}

de esta forma hemos implementado un pequeñoo framework que usa closures para hacerle consulta al listado de producto que retornen true o false, al igual que el select de ruby, por ejemplo el servicio anterior de si un producto pertenece a una categoría sería

public List pertecenenAUsandoClosure(List l, final String categoria) {
    return query(l, new QueryProduct() {
        public boolean isTrue(Producto p) {
            return p.perteneceA(categoria);
        }
    });
}

o entonces, conocer los que tienen un precio mayor a,

public QueryProduct precioMasAlto(final Producto p, final double precio) {
    return new QueryProduct() {
        public boolean isTrue(Producto p) {
            return p.getPrecio() > precio;
        }
    };
 }

Nota *: Esto es muy parecido a la implementación de templates, de hecho la forma en que es posible implementar closures en C o C++ es a través de templates.

Como pueden ver, esta solución es bien mas elegante, y genérica, aunque debemos reconocer la excesiva cantidad de código que necesitamos. Por otra parte a pesar que de esta forma simulamos los closures, en realidad no lo hace en su totalidad, pues un closure debe ser capaz de ser construido teniendo acceso a variables de contexto que existan en el momento de su definición y que a pesar que el closure sea invocado incluso cuando estas variables no existan más sea capaz de usarla como si fuera local a la invocación del closure.

Conclusiones:

Los closures son mecanismos que facilitan la vida del programador simplificando el código y haciendolo mas reusable y elegante, en el caso de Java, considero que Sun y James Gosling debían haber pensado en incluirlos de forma nativa evitandonos tener que escribir código para simularlo.