Ceylon 1.2

http://ceylon-lang.org/blog/2015/10/29/ceylon-1-2-0/

Pues al fin, después de un año de arduo trabajo, hoy liberamos Ceylon 1.2.0. Trae muchas, muchas cosas nuevas:

  • API para serialización
  • constructores
  • desestructuración para declaraciones
  • Expresiones inline: if, switch, let, object
  • Soporte para declaraciones nativas
  • Un IDE con varias mejoras
  • Soporte a Android en el IDE

Les explico algunas de estas:

Serialización

Dado que Ceylon compila a varias plataformas, el tema de serialización se complica. Hemos visto cómo Java incluyó una implementación de serialización en su JDK y resultó no ser muy eficiente, lo cual ha causado que aparecieran varias implementaciones alternas: protobuf, thrift, etc. Es por esto que decidimos diseñar una API para serialización, de la cual podrá haber varias implementaciones con distintos objetivos: que sea compacta, rápida, etc y funcione en una sola plataforma, o que sea multiplataforma (probablelmente a expensas de desempeño, etc).

Esto permitirá comunicación entre aplicaciones escritas en Ceylon aunque corran en distintas plataformas (JVM, JS, LLVM, etc).

Constructores

Originalmente, una clase tenía un solo constructor. Pero se ha visto la necesidad de que en vez de eso, una clase pueda tener varios constructores. No funcionan igual que en Java, hay algunas diferencias en cuanto a sus mecanismos internos, pero lo cierto es que permiten mayor flexibilidad en los casos en que se requieren. También hay constructores sin argumentos, que sirven para tener singletons dentro de una clase.

Por supuesto todavía se pueden definir clases con inicializador como antes, eso no se vio afectado.

  • Desestructuración
  • La desestructuración (destructuring) consiste en poder extraer datos de ciertos objetos y poder asignarlos a nuevos valores. Por ejemplo si se tiene una tupla, se pueden obtener sus elementos de manera individual en una sola declaración:

    value [uno,dos,tres] = devuelveTuplaConTresElementos();
    value llave->valor = devuelveEntry();
    value [k1->v1, e2] = devuelveTuplaConDosEntries();
    value [primero, *resto] = devuelveTuplaDeDosOMasElementos();
    for ([x, y, k->v] in tuplaConDosElementosYUnEntry) {
        ...
    }
    if (exists k->v = entryONull) {
        ...
    }
    if (nonempty [primero, segundo, *resto] = secuenciaDeAlMenosTresElementos) {
        ...
    }

    Es similar a una forma muy simple de pattern matching.

    Expresiones inline

    Ahora if puede ser una expresión, al igual que switch. Y ya tenemos la expresión let, muy útil para realizar cálculos intermedios. También hay expresiones object, lo que permite simplificar algo como esto:

    Algo metodo() {
      object retorno extends Algo() {
        ...
      }
      return retorno;
    }

    En algo un poco más simple:

    Algo metodo()
      => object extends Algo() {
        ...
      };

    Expresiones con switch e if:

    value uno = if (condicion) then 1;
                else 2;
    value dos = switch(expresion)
                case (is Integer) 1;
                case (is String) 2;
                else 3;

    Y finalmente, así es como funciona let:

    value x = let(
        e="K"->1,
        k = e.key,
        v = e.item) [v, k];
    print(x); //imprime [1, "K"]

    Declaraciones nativas

    Hay casos en los que la implementación de ciertos métodos cambia según la plataforma, porque en algunos casos se puede usar interop con código externo para una plataforma específica. En esos casos se pueden definir dependencias en el módulo que sólo aplican para cierta plataforma:

    module ejemplo "1.0" {
      native("jvm") import java.base "7";
    }

    Cuando se hagan imports de paquetes de ese módulo, el compilador valida que esas declaraciones únicamente sean utilizadas dentro de código marcado como nativo:

    import java.util { JDate=Date };

    shared native printDate();

    shared native("jvm") printDate() => print(JDate());

    shared native("js") printDate() {
      dynamic {
        print(Date()); //se genera como "new Date()"
                             //porque Date es una declaración dinámica,
                             //no se conoce su tipo en tiempo de compilación.
      }
    }

    Otra cosa nueva es que también nuestro IDE web ha mejorado bastante, ahora pueden guardar sus ejemplos en gists de github.

    En fin, muchas novedades, vale la pena que revisen aunque sea el IDE web, den una ojeada al tour en la página oficial ceylon-lang.org e incluso instalen el IDE, que es un plugin para Eclipse, para poder probar esta nueva versión de Ceylon.