Ceylon

El lenguaje de programación creado por Gavin King para aplicaciones empresariales

Reseña del Taller de Ceylon: Conceptos Basicos (y experimentos no tan basicos). Primera Parte

El sábado pasado asisti al taller de Ceylon, en el taller vimos diferentes temas: Conceptos básicos, Clases, Manejo de Nulos, Uniones e Intersecciones, Funciones, Iterables

En la sección de Conceptos Básicos vimos al típico hola mundo:

void hello() {
    print("¡Holá, Mundo!");
}

En Ceylon un programa es simplemente una función de primer nivel sin parámetros.

Vimos que cuando una funcion sólo devuelve una expresión, se puede abreviar usando la "flecha gorda"

void helloName() => print(greeting("Ceylon"));

Y tambien nos introdujeron a los parametros variadicos (los que pueden aceptar multiples valores):

Integer sum(Integer* numeros) {
    variable value sum = 0; //Los valores asignables deben anotarse con "variable"
    for (x in numeros) {
        sum+=x;
    }
    return sum;
}

Una de las caracteristicas mas interesantes de Ceylon es que puede inferir el tipo de una
declaración local.

void inferredTypes() {
    Integer time = process.milliseconds;
    value nl = process.newline;
    function sqr(Float float) => float*float;
}

Ceylon: comparativa con otros lenguajes

Como ya se ha escrito aqui en este sitio, Ceylon es un lenguaje de programación en desarrollo que pretende tomar lo bueno de Java y olvidarse de lo malo.

¿Cómo compilo/ejecuto un programa en Ceylon?

Antes de comenzar comenzar debes decargar la versión actual 0.4 (Analytical Engine).

Compilar:

ceylon compile source\programa.ceylon

Ejecutar:

ceylon run default

El clásico programa Hola mundo

En Ceylon.

holamundo.ceylon

doc "Esto se usa para documentar el programa"
by "el que escribe el programa"
void run(){
  print("Hola mundo");
}

Si todo sale bien debe imprimir:

"Hola mundo"

En Groovy.
holamundo.groovy

println "Hola mundo"

En Python.
holamundo.py

print "Hola mundo"

En Scala.
Holamundo.scala

object Holamundo{

 def main(args: Array[String]){
   
   println("Hola mundo");
}

}

JavaOne 2012 charlas técnicas en YouTube

El equipo del Oracle Learning Portal publica las charlas técnicas impartidas en la JavaOne 2012 en su canal de YouTube.

Las charlas son variadas y no tienen desperdicio, las pongo aquí para que las puedan aprovechar.

JavaOne 2012 Technical Tracks:

  1. Core Java Platform (69 videos)
  2. Development Tools and Techniques (75 videos)
  3. Emerging Languages on the JVM (35 videos)
  4. Enterprise Service Architectures and the Cloud (66 videos)
  5. Java EE Web Profile and Platform Technologies (81 videos)
  6. Java ME, Java Card, Embedded and Devices (78 videos)
  7. JavaFX and Rich User Experiences (48 videos)

Y aquí el canal de Oracle Learning Portal.

Ejemplos en Ceylon

Aquí les dejo unos código muy sencillos en este lenguaje.

Game Of Life en Ceylon

En el Code Retreat que hubo en Agosto de 2012, el reto fue implementar el famoso Game of Life, en parejas. En mi equipo, @juwe y yo lo desarrollamos en Ceylon (no me impuse; él se animó, jejej).

Apenas hoy lo pude subir a un repositorio que tenemos en GitHub especialmente para ejemplos de Ceylon, después de darle una buena actualizada al código porque han habido varios cambios en la sintaxis y en el módulo de lenguaje desde que escribimos esto originalmente: ya teníamos comprensiones, funciones de orden superior, funciones anónimas y varias otras cosas, pero no teníamos por ejemplo el assert, tuplas, ni la sintaxis actual para secuencias y colecciones iterables; la sintaxis para funciones anónimas cambió ligeramente, al igual que la de parámetros variádicos (los famosos varargs).

Comprehensiones en Ceylon

Las comprehensiones (o algo que se les parezca) son una característica ya prácticamente obligatoria en los nuevos lenguajes, al menos si quieren ser considerados cool. Y Ceylon no se queda atrás.

Las comprehensiones en Ceylon funcionan usando una variante especial de for, la cual acepta una sola expresión, en vez de un bloque de código. La expresión puede ser a su vez otro for, o bien un if, que actúa como un filtro, o cualquier otra expresión que devuelva algún valor. Todo eso termina siendo azúcar sintáctica para crear y devolver un objeto Iterable que se puede pasar en invocaciones a métodos o funciones que esperan argumentos secuenciados (de los que terminan con elípsis), o usarse directamente en cualquier lugar donde se pueda usar un Iterable.

Esto a fin de cuentas puede ser más poderoso que tener métodos como map y filter en las colecciones, y además permite hacer implementaciones más eficientes, ya que los iteradores intermedios involucrados se van utilizando conforme se necesitan, en vez de tener que procesar completamente una colección antes de pasar a la siguiente fase.

Si usan Groovy o Scala, puede que ya estén familiarizados con algunas de estas operaciones. Por ejemplo, tomar una lista de palabras y devolverlas en reversa:

["hola", "mundo", "javaMexico", "Ceylon"].collect { it.reversed() } //Groovy

List("hola", "mundo", "javaMexico", "Ceylon").map { _.reverse } //Scala

for (w in { "hola", "mundo", "javaMexico", "Ceylon" }) w.reversed; //Ceylon

Funciones en Ceylon, segunda parte

En mi post anterior, hablé acerca de las funciones de orden superior, la manera en que se pasan referencias a métodos, cómo se invocan, etc. Pues bien, ha habido bastante progreso en Ceylon, en varias áreas, y una de las que considero importantes es precisamente el manejo de funciones; algunas de las cosas que mencioné en ese post han cambiado, mientras que ha surgido funcionalidad nueva que no estaba disponible previamente. Así que veamos los cambios:

Callables

Primero que nada, ya no tenemos la restricción de que un Callable no podía ser invocado; ahora ya se puede, por lo que esto ya es válido:

value obj = MiClase();
Callable<String,Integer> f = obj.metodo;
String s = f(1);

La otra forma sigue siendo igual de válida:

value obj = MiClase();
//Aqui usamos inferencia de tipos
function f1(Integer x) = obj.metodo;
//Aqui ya lo definimos de manera estática
String f2(Integer x) = obj.metodo;
String s1 = f1(1);
String s2 = f2(2);

Argumentos por nombre

En Ceylon hay dos formas de hacer una invocación: usando argumentos posicionales (que es la manera en que todo mundo está acostumbrado a hacerlo) o usando argumentos nombrados (que no todos los lenguajes tienen y los que lo tienen, usan distintas sintaxis).

Ceylon M2

El segundo release de Ceylon, M2 aka "Minitel", ya está disponible.

Algunos de los cambios más importantes desde M1 que salió en diciembre, están:

  • Interoperabilidad con Java - ya se puede invocar código Java desde Ceylon, con algunas restricciones pero en general ya está funcionando.
  • Referencias a funciones y métodos - con esto hay bastante avance en lo que respecta a funciones de orden superior; ya se pueden pasar referencias a métodos y/o funciones como parámetros a otros métodos/funciones y también puede haber métodos/funciones que devuelvan Callables. Asimismo, se pueden definir métodos o funciones simplemente asignándoles una referencia a otro método o función que tenga la misma firma.
  • Performance - se optimizaron las operaciones aritméticas con Integer y Float, así como algunas operaciones que requieren boxing/unboxing (principalmente para interoperar con Java)
  • SDK más completo - El SDK ya incluye varias interfaces y clases para colecciones: Collection, Array, List, Map, Set, FixedSized, etc.

Funciones de orden superior en Ceylon

Ceylon tiene una característica que en lo personal me parece muy atractiva, algo que en otros lenguajes anuncian con gran fanfarria pero en Ceylon no se ha hecho tanto barullo. Es algo que creo que ayudará mucho para el diseño de APIs en el futuro cercano. Se trata de las funciones de orden superior.

Visto de manera simple, las funciones de orden superior son funciones que reciben otras funciones como parámetros, o bien que devuelven funciones como valor de retorno. El concepto realmente no es complejo; el truco en lenguajes de tipado estático está en que la sintaxis no sea compleja (en lenguajes dinámicos es muy sencillo pasar una referencia si no se tiene que indicar el tipo de retorno de la función, ni su número ni tipo de argumentos).

Una cosa muy necesaria para poder manejar funciones de orden superior en un lenguaje de tipado estático, es tener un tipo que las represente. En el caso de Ceylon, tenemos la clase Callable. Podemos usar este tipo para guardar la referencia a un método de un objeto por ejemplo. Suponiendo que tuviéramos una clase MiClase con un método metodo que reciba un entero y devuelva un string, entonces podemos hacer esto:

MiClase obj = MiClase();
Callable<String,Integer> f = obj.metodo;

Ojo, no es lo mismo obj.metodo() (lo cual es una invocación al método) que obj.metodo, que es simplemente obtener la referencia a ese método; a partir de entonces se puede manejar como una función.

El balance entre el uso de métodos como operadores.

Estaba escribiendo una respuesta al post de ezamudio Operadores en Ceylon pero como siempre me extendí más de la cuenta y mejor cree esta entrada separada.

El tema es la sobre carga de operadores en Ceylon.

Es interesante tratar de alcanzar el balance entre el uso de operadores y métodos en un lenguaje de programación.

Por un lado, si se permite que cualquier método se pueda utilizar como operador, se puede terminar creando código que solamente el autor del programa o la biblioteca entienda y eso cuando aún lo tiene fresco en la mente. Me parece que este es una de las críticas más fuertes hacía C++ y a Scala ( aunque Scala además permite una sintaxis diferente para la invocación de métodos que es sin usar punto )

Por otro lado si se prohibe del todo se tiene un lenguaje que es sumamente claro y fácil de entender por cualquiera pero que resulta tedioso porque el programador tiene que escribir toooodo el nombre del método y no simplemente un operador ( Java , Javascript y Go por ejemplo )

Distribuir contenido