java 7

hace algunos días platicando con un amigo me comento que le había llegado la invitación para la presentación de la java 7 que según va a ser en los ángeles ... y me preguntaba que era lo nuevo o diferente que iba a traer la versión 7 comparada con la actual?.......alguna idea?

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

closures, lambdas (tal vez)

Pues lo principal eran closures y lambdas pero creo que ya ambas cosas las quitaron para poder salir con algo, así que la verdad no sé qué traiga de nuevo. Creo que iban a meter también una anotación tipo @Property que le pegas a una variable privada para que te haga los setter y getter al momento de compilar, sin que los tengas que teclear tú (o generar con un IDE).

Yeap, los closures (

Yeap, los closures ( funciones anonimas ) van a salir hasta la v8 :

Aquí va una lista:

http://openjdk.java.net/projects/jdk7/features/

El más interesante el JSR 334 project coin que tendrá:

  • String en switch (  switch ( comando ) { case "EXIT" : System.exit(0); case "HELP": System.out.println("ja, ja"); break; } )
  • Nuevas literales de int ( ie int diez = 0b010; y  int mil = 1_000; )
  • Multicatch ( no exactamente pero tipo  try { blah(); } catch( OneException, TwoException ) { }
  • Operador diamante ( bah... ) List<Integer> i = new ArrayList<>();
  • try with resources ( similar a using in C# )
  • Invocación simplificada de vargs. Aún no entiendo este, pero es como para agregar más tipeo estático. La verdad no sé.

No todos los cambios del project coin van a lograrse en Java7, algunos serán diferidos para Java8.

Otros cambios son también muy interesantes, pero no van sobre el lenguaje, sino por ejemplo la arquitectura del class loader.

Chequen la lista.

Imagen de ezamudio

pfff

No me emociona mucho la lista. Pero bueno, el cambio de Java 1.3 a 1.4 tampoco fue nada emocionante, solamente mejor performance, pero casi nada de cambios en el código (introdujeron java.nio que ahora es casi casi obsoleto). De 1.4 a 5 sí fue más interesante, con la introducción de generics, autoboxing, tipos de retorno covalentes, java.util.concurrent, anotaciones... de 5 a 6 lo que más recuerdo es que corrigieron unos bugs en ConcurrentHashMap que sí me estaban afectando, y pues metieron también una manera de hacer web services en JavaSE (que funciona en algunos casos, pero en realidad no he podido dejar de usar Axis) y creo que integraron al JDK ya cosas como la biblioteca de activation.

Algunos usan esto como argumento para decir que Java ya no es una plataforma innovativa y que solamente se complica cada vez más, etc. Esto tiene algo de cierto en JavaEE, donde todo lo nuevo que meten para EJB, JCA, JDO, IoC, etc son refritos de los estándares que hay de facto en la industria, como Hibernate y Spring. Pero para mí también significa que Java ya es una plataforma bastante madura y por lo tanto no necesita tantas cosas nuevas en cada versión.

Lástima que retrasaron nuevamente lo de closures y lambdas; eso es algo que sí considero de alto impacto; pero no es tan grave, finalmente ya tenemos Groovy que permite usar closures en la JVM. Y los lenguajes como Groovy, Clojure, Scala, etc que funcionan sobre la JVM, aunque le tiren mucha caca a Java, por algo escogieron la JVM en vez de hacer la suya propia o usar el CLR de Mono/.NET o alguna otra.

Imagen de ArenasMx

ohh

esperaba o imaginaba que pudieran mejorar algunos aspectos de la gui pero pues creo que se fueron por implementar algunas otras cosas lambas y closures que con el debido respeto no se ni para que son :S

Imagen de ezamudio

GUI, closures

También vienen algunas cosas de GUI: Un L&F llamado Nimbus, componentes nuevos (JLayer), soporte para ventanas translúcidas y con distintas formas... eso lo vi en la liga que puso Oscar.

Los closures son en realidad muy útiles. En Java te permitirán mezclar OOP con programación funcional. Hoy mismo ya puedes usarlos pero en Groovy (que compila a bytecode Java). Una manera sencilla de verlo es que un closure es una función o método pero que no está asociado a ninguna clase u objeto en particular, y además se puede pasar como parámetro a otros métodos o closures. El ejemplo típico es que por ejemplo las listas en Groovy tienen métodos que reciben closures como parámetro, y el closure tiene un argumento que es un elemento de la lista, y depende del método, se espera que el closure devuelva algo. Y entonces se itera sobre cada elemento de la lista y se invoca el closure con cada elemento:

List lista = ['elem1', 'elem2', 'elem3']
lista.each { item ->
  println item
}

Ahí el closure es { item -> println item }. Es un closure que recibe un parámetro, llamado item, y lo único que hace es imprimirlo. El método each de la lista, va a invocar ese closure con cada uno de sus elementos. Ahí definí el closure estilo "inline" pero lo puedo definir en otro lugar y pasarlo como parámetro:

def imprime = { item -> println item }
//Se pasa como parámetro al método each (los paréntesis son opcionales)
lista.each(imprime)
//También se puede invocar como si fuera un método
imprime("hola")

Y obviamente tú puedes hacer métodos que reciban closures como parámetros, de modo que los invoques dentro de tu método. En Java hay una manera de hacer algo similar pero es más limitado: tienes que definir una interfaz con el método que quieres invocar dentro de tu método, y recibes un parámetro con un objeto que implemente esa interfaz. De entrada, para poder implementar tu método ya tuviste que definir una interfaz, y si yo quiero invocar tu método, debo implementar tu interfaz en uno de mis objetos, para definir el método que vas a invocar, etc. Muy enredoso, es más sencillo definir un closure (velo como una especie de "método flotante" o "errante") y pasarlo como pasas un String o cualquier otro objeto.

Pero a fin de cuentas, como dice Oscar, esto ya lo pasaron hasta la versión 8.

Imagen de ezamudio

cosas nuevas

De lo nuevo, lo más interesante que veo es el JSR292, porque eso va a darle mejor performance a Groovy, Scala, etc; el jsr166y para concurrencia, algoritmos para ECC, JDBC 4.1, y lo de Nimbus.

Imagen de ArenasMx

ahhh orale ahora si que ya

ahhh orale ahora si que ya le vi las posibles aplicaciones de closures, una forma mas rapida y expedita de implementar una interfaz, y yo que apenas le estaba hechando la mano a las interfaces y como definirlas ahora salen con esto :S tendre que volver a empezar

En el proyecto coin, va a

Project coin
En el proyecto coin, va a incluirse también ( aunque perdí la referencia a esto ) literales para listas y mapas:

List<Integer> numeros = [1,2,3,4,5];
Map<Integer,String> ids = {1 : "Oscar" };

Pero no me hagan mucho caso, quizá ya se arrepintieron de eso o lo pusieron para la Java 8.

Sobre la estabilidad del lenguaje
Java tiene como ventaja ( y desventaja al mismo tiempo ) ser un lenguaje estable. Así fue planeado desde el principio, y así ha sido su historia. Pocos cambios en la sintaxis para perservar la compatibilidad.

Otros lenguajes pueden hacer tantos cambios tan pronto que se vuelven incompatibles entre versiones. Pero en Java siempre se ha preferido hacer cambios no tan dramáticos, y aunque para algunos eso lo hace menos atractivo, también es cierto que para muchos otros, lo vuelve bastante confiable.

Closures
Sobre los closures, es un nombre raro, pero en sí son simplemente funciones ( o métodos ) anónimos, nada más.

Es verdad que Groovy y Clojure ( y claro JRuby y varios más ) los tienen, pero estos tienen la desventaja de ser lenguajes de programación dinámicos ( que para otros es ventaja ) En el caso de Scala es distinto porque también lo tiene, pero ahí es estático.

En específico para Java 8 lo que se planea es poder traducir transparentemente los SAM types ( single abstract method )

Hoy en día se usan clases anónimas

Por ejemplo para ordenar hoy en día una lista podemos usar el método Collections.sort( List )

...
List<Integer> numeros = Arrays.asList(4,2,7,4,9);
Collections.sort( numeros );
System.out.println( numeros ); // imprime [2, 4, 4, 7, 9]
..

Así se hace el ordenamiento "natural" ( para los numeros de menor a mayor, para las cadenas, alfabeticamente etc. )

Pero que pasa si lo queremos al revés? Existe otro método que recibe un comparator ( un comparator es una interfaz que es llamada para comparar dos elementos )

Así podemos definir un ordenamiento "customizado" ( de mayor a menor ) :

List<Integer> numeros = Arrays.asList(4,2,7,4,9);
Collections.sort( numeros , new Comparator<Integer>(){
  public int compare( Integer a, Integer b ){
       return b - a;

    }
});
System.out.println( numeros ); // imprime [9, 7, 4, 4, 2]

El código:

new Comparator<Integer>(){
  public int compare( Integer a, Integer b ){
       return b - a;
  }
}

Define una clase anónima ( en realidad, subclase, pero en fin ) , se llama anónima porque no tiene nombre. Esta clase define ahi mismo, el comportamiento de la clase, en el ejemplo, comparar b contra a.

La necesidad de los clousures
Pues bueeeeeno, así ha sido Java desde la versión 1.2, y era feliz.

Resulta, que hay otra forma de hacerlo, que es con métodos anónimos ( funciones anonimas, blocks, closures o como se le llame ) y que existen desde pues casi siempre, por ejemplo en Smalltalk, pero que han retomado relevancia, con los lenguajes de programación dinámicos. Por ejemplo en Javascript se usan muchísimo, un ejemplo en jQuery:

// Muy común en  Javascript:
$(document).ready(function() { //<-- funcion anónima pasada al vuelo a.k.a. closure
   // un monton de cosas.
});

Por ejemplo, ¿no sería bueno poder pasarle nomás el método para comparar, en vez de toda la subclase?

Collections.sort( numeros ,
  public int compare( Integer a, Integer b ){
       return b - a;
    }
);

Pero como no se puede definir un método dentro de una llamada a funcion se necesita este nueva sintaxis ( esta sintaxis no necesariamente será la final ):

Collections.sort( numeros,  #(Integer a, Integer b )( b - a ) );

Conversiones SAM
Como sería mala idea modificar toda la biblioteca de Java para que ahora reciban además de interfaces, recibiera ahora también los closures: ( ie Collections.sort( List, Comparator ) y luego (Collections.sort( List,  #() ) ) por que eso automáticamente rompería casi todo el código existente, ya que si alguién implementa una interfaz y ahora esa interfaz tiene un nuevo método que la clase ya no va a implementar; lo que se va a hacer es que exista una transformación automágica cuando el el tipo tenga un solo método.

Ejemplos de interfaces que tienen un solo método: Comparator ( bueno tiene 2 pero ... viene referenciado ), Runnable, ActionListener, y varios varios más9.

Entonces cuando se escriba:

Collections.sort( number , closure );

El compilador va a convertir ese closure a una clase anónima por nosotros de hecho así es como se implementan los closures en los otros lenguajes, metiendo clases anonimas por debajo, ej. Scala, Clojure, Groovy, Ryz - :")

Metodos de extensión
Una última adición para Java 7 8 será para complementar estos closures, un mecanismo similar a los extensión methods in C# y a los implicits en Scala de tal forma que si el tipo no tiene el método, el compilador busque un método que sea factible y este en scope y se lo aplica.

Ejemplo ( sintaxis Java imaginaria )

import static extension java.util.CollectionExtension.*;

...
numeros.sort( #(int a, int b )( b - a ));
..

// En CollectionsExtension:
package java.util;

class CollectionExtension {
 ...
  public static extension void sort( List target, Comparable comparator) {
      Collections.sort( target, comparator);
  }
...
}

Pero se traen un jaloneo en la definicion de todo esto. Por eso lo defirieron para Java 8.

Más links

http://cr.openjdk.java.net/~mr/lambda/straw-man/
http://blogs.sun.com/mr/entry/plan_b_details
http://openjdk.java.net/projects/lambda/
http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-3.html
http://www.baptiste-wicht.com/2010/05/oracle-pushes-a-first-version-of-c...

Autopromoción:

En Ryz, los blocks con SAM se definen así
Los métodos de extensión asá

Aunque a ambos les falta muchísimo camino por recorrer. Originalmente yo pensé estos features para el lenguaje, solo para descubrir que ya estaba todo esto en camino :-/ Por eso le decía que es muy difícil crear algo que sea al mismo tiempo original y utilizable.

Chau!

Que al parecer va a ser lo

Que al parecer va a ser lo mejor para estos lenguajes (moverse de VM o crear la propia).

Con los cambios de Java, si es cierto. Ya cómo quien dice falta mejorar lo existente, no es (tan) necesario agregar nuevas cosas, aunque las closures y las lambda también serían algo genial y un punto más para Java. Lástima que no hay tiempo y recursos para todo, y menos dejando de lado a la comunidad (Oracle, gracias de nuevo).

Imagen de ezamudio

Mejor?

Crees que lo mejor para Groovy y Scala sea cambiar de VM? Yo no lo creo. Pero en fin, eso ya es otra discusión.

Imagen de bferro

Funciones anónimas !=closures

Los closures no son solamente funciones anónimas. Hay mucho más en ese concepto. Por eso se llaman closures. Si no hay "free variables" que se evalúan en el contexto léxico, entonces no hay "clausura".

Imagen de neko069

A mí me hubiera gustado que

A mí me hubiera gustado que metieran características estilo ZeroTurnAround con su JRebel..... a ver cuando se me hace ver tal cosa....

De acuerdo: anonFunc !=

De acuerdo: anonFunc != closures

De acuerdo, pero el post estaba ya suficientemente largo como para meter más conceptos.

La diferencia fundamental es que el closure es una funcion que "se evalua, en donde se define".

En Go, por ejemplo, se puede definir una funcion A que devuelva otra funcion B.

Si existe una variable c dentro de la funcion A, entonces la funcion B puede evaluarla aún cuando ya haya terminado:

Ejemplo

// En go
func fib() func() int { // la funcion A "fib" que regresa una funcion que regresa un int
        a, b := 0, 1 // enteros a y b definidos  dentro de la funcion  A pero fuera de la funcion  B
        return func() int { // la funcion B
                a, b = b, a+b //accederlo
                return b
        }
}

Esto se lee así:

1.- fib() regresa "func()" que regresa un entero

2- a y b son variables locales de "fib" que se inicializan a 0 y 1

3.- Regresa una nueva funcion anonima ( closure en este caso ) que tiene acceso a las variables a y b.

Al ser usado, aún pueden ser accedidas ( no salen se alcance )

// Usarlo
func main() {
        f := fib() // obtener la funcion
        println(f(), f(), f(), f(), f()) // invocarla varias veces.
}

La salida es:

1 2 3 5 8

Los valores se calculan usando las funciones a, b

Los closures, son "funciones de primer nivel" entendiendo por esto que pueden ser asignadas a variables, pasadas como argumentos, y almacenadas en estructuras de datos.

Las funciones anónimas, no necesariamente hacen todo esto.

Re: Mejor?

Pues bueno, es cómo todo ventajas y desventajas. De momento el camino javalesco no se ve nada claro, tienes a gente importante saliendo y gritando que no quieren nada con Java, sobretodo gente importante (ej. Apache).

Por otro lado si lo ves desde el punto de vista práctico, no existe alguna VM comparable con la JVM (la cual ya es estable y madura).

Cómo bien dices esa es otra discusión, pero pues no sé, no me gusta cómo va llevando Oracle el rumbo de Java (eso de andar capando NetBeans, haciendo que personas o proyectos cómo Glassfish ya hayan sido descontinuados, etc.).

Nos queda sólo esperar y ver quien tenía la razón =P