Ceylon: Introducción rápida

Una forma de contribuir con Ceylon, o con cualquier otro proyecto de open source, es escribir en la lengua de Cervantes (modificada por Bárbaro), mucho de lo que ya está escrito en el sitio de Ceylon en la lengua de Shakespeare ( modificada por Gavin). Mi intención es traducirlo todo al español y confío en Manzanero con su semana de más de 7 días.
Por lo pronto lo que sigue es una traducción libre de Quick Introduction

Introducción rápida

Es imposible captar la esencia de un lenguaje de programación observando solamente la lista de características. Lo que realmente hace al lenguaje es la combinación de esa pequeñas cosas trabajando juntas. Y resulta que es imposible apreciar esa sinergia sin escribir código. En esta sección vamos a mostrar de manera rápida lo suficiente de Ceylon para lograr un interés suficiente que te conduzca a probar el lenguaje. Lo que sigue por supuesto que no es una lista completa de las características del lenguaje.

Una sintaxis legible y familiar

La sintaxis de Ceylon es a "diez de última" derivada del lenguaje C. Por lo que si eres un programador de C, Java o C# te sentirás como en casa. De hecho, uno de los objetivos del lenguaje es que gran parte del código sea legible por personas que no son programadores de Ceylon y que no han estudiado la sintaxis del lenguaje.
Sigue, por ejemplo, el código para escribir una función:
 
Y el código para una clase:
 

Y, si queremos crear e iterar la secuencia creada:
 
Si estos códigos te aburren, es porque precisamente esa es la idea - son aburridos porque los entiendes inmediatamente.

La sintaxis declarativa para estructuras arbóreas

Las estructuras jerárquicas son tan comunes en computación que para ellas tenemos lenguajes dedicados para lidiar con ellas, como es el caso del lenguaje XML. Pero cuando tenemos código procedural que interactúa con estructuras jerárquicas, el mismatching (lo dejo en inglés) de impedancia entre XML y nuestro lenguaje de programación es la causa de toda suerte de problemas. Ceylon entonces, incorpora una sintaxis "declarativa" especial para definir estructuras jerárquicas. Esto es especialmente útil para crear interfaces de usuario:
 
La utilidad de esa sintaxis declarativa va mucho más allá del ejemplo anterior y nos brinda un gran fundamento para expresar todo, desde guiones (scripts) para construir proyectos hasta suites de prueba:
 
Cualquier marco de trabajo (framework) que combina Java y XML requiere de herramientas de propósito especial para lograr la comprobación de tipos y la asistencia en la autoría. Los marcos de trabajo de Ceylon, que hacen uso del soporte incorporado (built-in) del lenguaje para expresar estructuras arbóreas, logran esto y mucho más "de gratis".

Tipado (typing) principal, tipos unión y tipos intersección

La sintaxis con sabor convencional de Ceylon esconde un sistema poderoso de tipos capaz de expresar cosas que otros lenguajes de tipado estático simplemente no pueden. Todos los tipos de Ceylon pueden, al menos en principio, expresarse por si mismos dentro del sistema de tipos. No existen tipos primitivos, ni arreglos ni otras cosas similares.
El sistema de tipos está basado en el análisis del "mejor" o tipos principales. Para cualquier expresión, puede determinarse su tipo más específico, sin analizar el resto de la expresión en la cual ella aparece. Todos los tipos usados internamente por el compilador son denotables, i.e, ellos pueden expresarse dentro del propio lenguaje. En la práctica, esto significa que el compilador siempre produce errores que los humanos ( o sea nosotros) pueden entender, aun en los casos cuando se trabaja con tipos genéricos complejos. El compilador de Ceylon nunca produce mensajes de error con tipos no denotables mistificantes como   en Java.
Una parte integrante de este sistema de tipos principales denotables es el soporte de primera clase para los tipos union e intersección. Un tipo unión es un tipo que acepta instancias de cualesquiera de los tipos de una lista:
 
Un tipo intersección es un tipo que acepta instancias de todos los tipos de una lista:
 
Los tipos unión e intersección son útiles y convenientes en el código ordinario. Aun más importante, ayudan a simplificar y a que las cosas sean más claras en situaciones donde otros lenguajes son complejos, especialmente en la inferencia de argumentos de tipos genéricos. Considere el siguiente código para secuencias:
 
El compilador en este caso infiere los tipos:
 
Esos son los tipos principales de las expresiones. No tuvimos la necesidad de especificar explícitamente esos tipos en ninguno de los dos casos.

Herencia mixin

Ceylon tiene clases e interfaces como Java. Una clase puede heredar solamente de una clase base y de un número arbitrario de interfaces. Una interfaz puede heredar de un número arbitrario de interfaces pero no puede heredar de una clase que no sea Object. A diferencia de Java, las interfaces pueden definir miembros concretos. Por tanto, Ceylon soporta un tipo restringido de herencia múltiple conocido como herencia mixin (no traduzco el término):
 
Lo que distingue a las interfaces de las clases en Ceylon es que las interfaces son stateless ( no traduzco el término). Esto quiere decir que una interfaz no puede contener directamente una referencia a otro objeto, no puede tener lógica de inicialización y no puede ser instanciada de manera directa. Ceylon, elegantemente evita la necesidad de realizar cualquier tipo de linearización de los super tipos.

Atributos polimórficos

Ceylon no tiene campos, al menos en el sentido tradicional. En su lugar, los atributos son polimórficos, y pueden ser refinados por una subclase, similar al refinamiento de los métodos en los lenguajes orientados a objetos.
Un atributo podría ser un valor simple:
 
Podría ser un getter:
 
O podría ser un par getter/setter:
 
En Ceylon no necesitamos escribir getters o setters triviales, ya que el estado de una clase siempre se abstrae completamente de los clientes de la clase.

null seguro en tipo y estrechamiento más seguro de tipos

No hay en Ceylon   ni cosa similar. Ceylon requiere de nosotros que declaremos de forma explícita que valores pueden ser nulos o que métodos pueden retornar nulos. Por ejemplo, si   pudiera ser null, tenemos entonces que declararlo como:
 
que no es otra cosa que una abreviación de:
 
Un atributo de tipo   podría referirse a una instancia real de   o podría referirse al valor   (la única instancia de la clase  . De suerte que, Ceylon no nos permite hacer nada útil con un valor de tipo   sin antes comprobar que no es   usando el constructo especial  .
 
De forma similar no existe en Ceylon  . En su lugar, hacemos uso de los constructos  y   para probar y estrechar el tipo de un valor en un solo paso. De hecho, el código anterior es realmente un atajo para escribir lo siguiente:
 

Subtipos enumerados

Es una mala práctica en la programación orientada a objetos escribir sentencias switch largas que manejen todos los subtipos de un tipo. Resulta tedioso extender un código escrito de esa manera.Al añadir un nuevo subtipo al sistema provocamos la ruptura de las sentencias switch. Por eso, en el código orientado a objetos, usualmente refactorizamos el código escrito de esa manera, usando un método abstracto del super tipo que se refina apropiadamente por los subtipos.
Sin embargo,hay una clase de problemas donde este tipo de refactorización no es apropiado. En la mayoría de los lenguajes orientados a objetos, estos problemas se resuelven usando el patrón "visitador". Desafortunadamente, una clase visitadora puede resultar más verbosa que una sentencia switch y no es más extensible. Hay, por otra parte, una ventaja significativa del patrón visitador: el compilador produce un error si añadimos un nuevo subtipo y olvidamos manipularlo en uno de nuestros visitadores.
Ceylon nos da lo mejor de ambos mundos. Podemos especificar una lista enumerada de subtipos cuando definimos un super tipo:
 
y podemos escribir una sentencia switch que manipule todos los subtipos enumerados:
 

Alias de tipos e inferencia de tipos

Las declaraciones de tipos totalmente explícitas pueden contribuir a que un código complejo pueda ser más fácil de entender. Pero hay otras ocasiones donde la repetición de un tipo genérico verboso atenta contra la legibilidad del código. Hemos observado que:

  1. las anotaciones explícitas de los tipos son de mucho menos valor para las declaraciones locales, y
  2. la repetición de un tipo parametrizado con los mismos argumentos tipo es común y extremadamente ruidoso en Java.

Ceylon ataca el primer problema permitiendo la inferencia de tipos para declaraciones locales. Por ejemplo:
 

Por otra parte, para las declaraciones que están accesibles fuera de la unidad de compilación en las que son definidas, Ceylon requiere una anotación explícita del tipo. Pensamos que eso hace al código más legible, nunca menos, y logra que el compilador sea más eficiente y menos vulnerable a desbordamientos de la pila.

Ceylon enfrenta el segundo problema usando alias para los tipos, que son muy similares a un typedef en el lenguaje C. Aun alias de un tipo puede fungir como una abreviación para un tipo genérico junto con sus argumentos tipo:
 
Fomentamos el uso de estas dos características del lenguaje donde y sólo donde ellas logren hacer que el código sea más legible.

Funciones de orden superior

Como la mayoría de los lenguajes de programación , Ceylon permite pasar funciones como argumentos a otras funciones.
Una función que opera sobre otras funciones es llamada una función de orden superior.Por ejemplo:
 
Cuando se invoca una función de orden superior, podemos pasar, una referencia a una función nombrada:
 
O podemos especificar la función argumento en línea, bien así:
 
O usando una invocación con argumento nombrado, como esto:
 
Es posible también pasar una referencia a un atributo o método miembro a una función de orden superior:
 

Genéricos simplificados con tipos totalmente reificados

Ceylon no soporta los parámetros tipo de wildcard al estilo de Java, no soporta los tipos raw(no traduzco el término) ni ninguna otra clase de tipo existencial. El compilador de Ceylon nunca usa tipo alguno "no-denotable" para razonar acerca del sistema de tipos. No hay en Ceylon restricciones implícitas sobre los argumentos tipo. De esta forma, los mensajes de errores relacionados con los genéricos siempre son entendidos por los humanos.
En lugar de tipos wildcard, Ceylon incluye información de la varianza en el sitio de la declaración. Un parámetro tipo puede marcarse como covariante (out) o contravariante (in) por la clase o la interfaz que declara el parámetro.
 
Ceylon tiene un sistema más expresivo e restricciones de tipos genéricos con una sintaxis más regular y más amplia. La sintaxis para declarar restricciones sobre los tipos en el parámetro tipo es muy similar a una declaración de clase o interfaz.
 
El sistema de tipos de Ceylon es totamente reificable. En particular, los argumentos de tipos genéricos son reificados, eliminando muchos problemas que resultan del borrado de los argumentos de tipos genéricos en Java.

Polimorfismo de operadores

Ceylon incluye un rico conjunto de operadores, incluyendo la mayoría de los operadores que soportan C y Java. Ceylon no soporta la sobrecarga real de operadores. Lo sentimos, no puedes definir el operador papa <+|:-) en Ceylon. Ni tampoco puedes redefinir el operador * con algo que nada tiene que ver con la multiplicación numérica. Sin embargo, cada operador predefinido por el lenguajes esta definido bajo cierta clase o interfaz, permitiendo la aplicación del operador a cualquier clase que extienda o satisfaga el tipo en cuestión. Llamamos a este enfoque polimorfismo de operadores.
Por ejemplo, el módulo del lenguaje Ceylon define la interfaz   como:
 
Y la operación   está definida para los valores que son asignables a  . La expresión siguiente:
 
es meramente una abreviación de:
 
De forma similar,   se define en términos de la interfaz  ,   en términos de la interfaz   y así con otros operadores.

Metaprogramación segura en tipos y anotaciones

Ceylon ofrece un soporte sofisticado para la meta programación, incluyendo un meta modelo seguro en tipos y eventos. El código genérico puede invocar miembros de manera reflexiva e interceptar invocaciones a miembros. Esta característica es más poderosa y mucho más segura en tipos, que la reflexión en Java.
 
Ceylon soporta las anotaciones a los elementos de un programa con una sintaxis racional. De hecho, las anotaciones son usadas para los modificadores del lenguaje como   y   (no son palabras reservadas de Ceylon) y también para incrustar la documentación de un API para el compilador de documentación:
 

Modularidad

Ceylon ofrece constructos para módulos y paquetes de nivel del lenguaje, de conjunto con control de acceso de nivel de lenguaje mediante la anotación compartida la cual puede usarse para expresar visibilidad pública, privada de módulo, privada de paquete y local de bloque para los elementos de un programa. No existe en Ceylon el equivalente de   de Java. Las dependencias entre módulos se especifican en el descriptor del módulo, que por supuesto se escribe en Ceylon:
 
El compilador de Ceylon produce directamente archivos de módulos   en repositorios de módulos. Nunca te enfrentas con archivos  
En ejecución, los módulos se cargan siguiendo una arquitectura de cargadores de clases de tipo peer to peer, basada en el mismo runtime de módulos que es usado por el núcleo de JBoss AS 7.

Toma el tour

Hasta aquí la introducción. Toma el tour de Ceylon para un tutorial a profundidad.

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

sitio oficial

De hecho se quiere tener el sitio disponible en varios idiomas; si pones este texto en el formato adecuado y mandas el pull request en github, lo podemos integrar al sitio oficial. esto es algo que ayuda mucho para la adopción del lenguaje.