Funciones-objeto y closures
Lo primero que hay que entender es la diferencia entre funciones como objetos y closures. Una función puede ser anónima o definida, pero también pueden ser objetos en si mismas. Esto nos permite utilizar funciones como argumentos, ser devueltas por otras funciones o ser almacenadas en estructuras de datos. Vamos, son objetos de primera clase o de primer orden.Un closure es una función más su entorno y estos pueden ser de igual forma tratados como objetos de primera clase, pero al contener un entorno, podemos acceder a variables (o funciones) de este entorno incluso cuando el mismo no este activo. Existen lenguajes que soportan funciones-objetos o closures o ambos, y muchos de los lenguajes funcionales en su mayoria utilizan funciones y funciones-closure.
Entonces, un closure, por ejemplo, nos permite definir una función que tiene acceso a una variable, así que podemos almacenar esta funcion en un objeto y acceder a ella. El contexto de la función no se limita sólo a los objetos a los que tiene acceso directo, pero también a las variables que obtiene vía el entorno.
¿Cómo encaja esto dentro de Java?
Veamos un ejemplo clásico de sort con un método anónimo:- anArray.sort(new Comparator
() { - public int compare(MyClass a, MyClass b) {
- return a.myProperty().compareTo(b.myProperty();
- }
- });
- anArray.sort( (a, b) => a.myProperty().compareTo(b.myProperty() );
- public List
squareIntegers( List iList) { - List
result = new ArrayList (iList.size()); - for (Integer i : iList){
- result.add(i*i);
- }
- return result;
- }
- iList = squareIntegers(iList);
- iList = iList.map( { Integer i => i*i } );
definición teórica de closure, es decir, un método que puede obtener o hacer "close over" sobre el contexto del código al que pertenece sería:
- public Collection
getSpanishDvd( Collection dvds ){ - return select( dvds, { Dvd aDvd => dvd.isSpanish() } );
- }
- public static
Collection select(Collection source, {T=>Boolean} predicate) { - Collection
result = new ArrayList (); - for (T o : source) {
- if (predicate.invoke(o)) result.add(o);
- }
- }
¿Son utiles los closures?
En lenguajes como Python llevan mucho tiempo discutiendo sobre la necesidad de lambda y la verdad es que IMO no son algo necesario, pero que es bueno tener a mano para cuando las circunstancias lo precisen. Este tema es parecido al de los for-each con Java6 donde muchas personas desconfiaban de la implementación de estos y de su utilidad. Como sucede con cualquier herramienta, es mejor entenderla antes de utilizarla para no terminar con código spaghetti que dificulte la lectura y el mantenimiento.Os recomiendo leer el libro SICP para comprender los closures en su totalidad y además un poco de Lisp.
No me gustan. En mi opinión ensucian el lenguaje.
ResponderEliminarSupongo que es como la película "el cubo" te gusta o la odias.
ResponderEliminarpara mi es un tema nuevo seguire leyendo y talvez al rato vuelva para dejar otra opinion
ResponderEliminar