Ceylon

Un article de Wikipédia, l'encyclopédie libre.
Aller à : navigation, rechercher
Ceylon
Apparu en 2011
Auteur Gavin King
Développeurs Gavin King
Paradigmes orienté objet
Typage Statique, fort
Influencé par C, Java
Système d'exploitation Multiplate-forme
Licence Apache Software License
Site web http://ceylon-lang.org

Ceylon (prononcé /sɨˈlɒn/[1]) est un langage de programmation open-source de haut niveau, fortement typé et au typage statique. Sa syntaxe se rapproche de celle de Java. Il peut être compilé sous forme de bytecode Java ou sous forme de Javascript. Il a été publié par Red Hat sous licence Apache v2. Il a été créé par Gavin King, créateur de Hibernate et de JBoss Seam.

Objectifs[modifier | modifier le code]

Face au vieillissement réel ou supposé du langage Java et du JDK, publié en 1995, et de sa faible évolution, les créateurs de Ceylon ont voulu créer un langage plus actuel. Les caractéristiques qu'ils revendiquent avoir voulu donner à ce langage sont :

  • Puissance, c'est-à-dire pourvu d'abstractions expressives, comme un typage fort et statique, des mixins, la gestion de tuples, les intersections, unions et énumérations de types,
  • Lisibilité, afin de permettre la lecture aisée d'un code inconnu, puisque il s'agit d'une activité s'imposant fréquemment aux développeurs. Dans ce but, Ceylon cherche à offrir une syntaxe simple, proche de Java, très régulière, c'est-à-dire utilisant toujours les mêmes structures syntaxiques pour les mêmes résultats, en utilisant du sucre syntaxique là où c'est utile.
  • Prévisibilité : Ceylon a pour but d'utiliser des règles simple et intuitive, d'éviter les cas particuliers et les effets de bord et de proposer des messages d'erreur signifiants.
  • Une plateforme : Ceylon fonctionne à la fois dans un environnement Java et dans un environnement Javascript. Il propose un SDK neuf et est totalement interopérable avec le SDK Java.
  • Modularité : Les applications développées avec Ceylon sont découpées sous forme de modules qui peuvent publiés et distribuées via Ceylon Herd, un référentiel de modules.
  • Outillage : Pour développer en Ceylon, un ensemble complet d'outils est proposé. Des outils en ligne de commande, ainsi qu'un IDE permettant la saisie prédictive, l'autocomplétion, la recherche, le refactoring, le debugging, etc.

Historique[modifier | modifier le code]

Ceylon a été présenté pour la première fois lors d'une présentation donnée par Gavin King à la conférence QCon[2] qui c'est tenue à Pékin du 8 avril 2011 au 10 avril 2011. Il travaillait sur le projet depuis deux ans à ce moment, c'est-à-dire depuis 2009[3].

La version 1.0.0 du langage a été publiée le 12 novembre 2013[4].

Syntaxe[modifier | modifier le code]

La syntaxe est proche de celle de Java. La documentation officielle indique qu'elle est inspirée de celle du C[5].

Exemple simple[modifier | modifier le code]

Voici un exemple classique de programme "Hello world" en Ceylon :

void hello() {
    print("Hello, World!");
}

Concepts fondamentaux[modifier | modifier le code]

Tous les codes sources sont des fichiers ayant une extension .celyon.

En Ceylon, tous les objets sont immuables par défaut. Pour qu'un objet ne soit pas immuable, il faut qu'il soit déclaré avec l'annotation variable.

Exemple :

La distinction entre variable locale et attribut d'un objet est plus floue que dans d'autres langages orientés objet. Une variable déclarée dans le corps d'une classe, mais qui n'est pas annotée par shared est une variable locale, à moins qu'elle ne soit utilisée dans une méthode annotée par shared.

Exemples :

Quand on affecte une valeur à une variable au moment de sa déclaration, et que cette affectation permet de déduire sans ambiguité le type de la variable, on peut omettre celui-ci. Il faut alors simplement utiliser le mot-clé value. Mais il n'est pas possible de faire ça si on veut déclarer la variable comme shared ou formal.

Exemple :

Classes[modifier | modifier le code]

Ceylon est un langage orienté objet par classes. La structure de base d'un programme en Ceylon est donc la classe. Une classe est incluse dans un package et un package est incluse dans un module.

Exemple :

shared class uneClasse(String uneChaine) {
 
    String uneAutreChaine;
    shared Float unReel;
 
}

Il n'y a pas de constructeur. La déclaration de la classe contient les paramètres qui doivent passés lors de l'instantiation d'un objet. Dans l'exemple, il faut lui passer une chaine en paramètre. Cette chaine fait implicitement partie des attributs de la classe. Cela signifie donc qu'il ne peut pas y avoir de surcharge de constructeur et qu'il n'y a qu'une seule manière d'instantier un objet.

Il n'y a pas de mot-clé permettant l'instantiation, comme new en Java ou en C++. On appelle simplement le nom de la classe comme une fonction.

Exemple :

L'encapsulation des données fonctionne de manière différente des autres langages dérivées de C++. Le mot-clé shared rend accessible un élément en dehors de son contexte d'origine. Ce qui veut dire que s'il est déclaré shared, un attribut ou une méthode sera visible en dehors de la classe, pour une classe, cela veut dire qu'elle sera visible par les autres classes du package et pour un package, qu'il sera visible par les autres modules.

Comme en Java, chaque classe est définie dans un fichier portant le même nom et se trouvant à l'endroit dans l'arborescence indiqué par le package.

Héritage[modifier | modifier le code]

Pour qu'une classe hérite d'une autre, on emploie comme en Java le mot-clé extends.

Exemple :

class Automobile(Float vitesseMax) extends Vehicule {
    shared default String description => "``modele`` "+super.description;
}

avec la classe Vehicule :

class Vehicule(Float vitesseMax, String modele) {
        shared actual String description => "``vitesseMax``";
}

On voit qu'il est possible d'accéder aux attributs de la classe-mère grâce à l'utilisation du mot-clé super. On voit que pour qu'un attribut de la classe-mère puisse être redéfini, il faut qu'il soit déclaré avec default. De même, la redéfinition doit être déclarée avec le mot-clé actual. Ce sel syntaxique évite les erreurs de redéfinition, comme par exemple la redéfinition par erreur ou l'erreur de nommage de l'attribut redéfini. La syntaxe pour la redéfinition peut être raccourcie en supprimant l'ensemble des mots-clé précédent le nom de l'attribut, y compris le type de données :

    description => "``modele`` "+super.description;

Cette syntaxe ne permet aucune annotation, pas même la documentation.

De manière analogue à Java, toute classe ne précisant pas une classe-mère hérite implicitement de la classe ceylon.language.Object.

Classes abstraites et interfaces[modifier | modifier le code]

  • Les classes abstraites sont déclarées avec l'annotation abstract. Les méthodes non implémentées et les attributs non initialisées doivent être déclarés avec l'annotation formal.

Exemple :

  • Une interface se déclare avec le mot-clé interface. De manière similaire à la version 8 de Java, il est possible de définir une méthode dans une interface, à condition de ne faire aucune initialisation d'attribut et de ne pas faire référence à un type extérieur à la classe.

Exemple :

L'implémentation d'une interface par une classe se fait à l'aide du mot-clé satisfies.

Exemple :

On voit qu'il est possible en Ceylon d'ajouter des attributs à une interface. Pour éviter toute ambiguité, il n'est possible pour une classe d'implémenter deux interfaces ayant un attribut de même nom que si celui-ci est provient d'une autre interface dont les deux premières héritent.

Exemple :

Il peut donc être nécessaire de factoriser délibérément des attributs communs à plusieurs interfaces dans une interface dont elles vont toutes hériter.

Exemple :

Les interfaces pouvant contenir des attributs et du code, il est possible de composer des classes par implémentation de plusieurs interfaces, la classe héritant alors des comportement déjà inclus dans ces interfaces. Ces interfaces se comportent alors comme des mixins.

Le même mot-clé satisfies est utilisé pour indiquer qu'une interface hérite d'une autre interface.

Exemple :

Classes anonymes et classes membres[modifier | modifier le code]

  • Une classe anonyme est définie au moment où elle est utilisée pour instantier un objet, par le mécanisme de l'héritage. On utilise le mot-clé object dans ce but.

Exemple :

Il faut garder à l'esprit que les déclarations d'objets en utilisant une classe anonyme reçoivent une closure contenant les données disponibles dans le contexte à ce point du code.

Exemple :

  • Il est possible de déclarer une classe à l'intérieur d'une autre classe. Contrairement au mécanisme de classes imbriquées en Java, en Ceylon, une telle classe est un membre à part entière de la classe qui la contient. C'est ce qu'on appelle une classe membre.

Exemple :

En conséquence, quand on créé une classe dérivée de la classe de niveau supérieur, il est possible de remplacer la classe membre par une de ses classes dérivées.

Exemple :

Dans une classe abstraite, il est même possible de déclarer une classe membre avec formal, afin que les classes héritant de la classe abstraite doive redéfinir la classe membre.

Exemple :

Iterables et séquences[modifier | modifier le code]

Un objet iterable est un objet qui permet de produire un flux de valeurs. Il faut pour cela que l'objet implémente l'interface Iterable de la bibliothèque standard de Ceylon.

Alias de type[modifier | modifier le code]

Afin de raccourcir et de factoriser le code, il est possible en Ceylon de définir un type comme un alias d'un ou plusieurs autres, y compris ses types paramétrés. C'est vrai pour les classes comme pour les interfaces.

Exemple pour une interface :

interface Repas => Set<Aliment>;

Exemple pour une classe :

class Alphabet({Caractere*} caractere) => ArrayList<Caractere>(caractere);

Dans le cas d'une classe, il faut définir les paramètres formels afin que la classe puisse être instantiée.

On peut également créer un alias nommé grâce au mot-clé alias. C'est indispensable pour créer un alias d'une union ou d'une intersection de types.

Exemple :

alias Lists => ArrayList|LinkedList;

Union, intersection et énumération de types[modifier | modifier le code]

Generics[modifier | modifier le code]

Packages[modifier | modifier le code]

A la différence de Java, un package est défini dans un fichier spécifique appelé package.ceylon. Il doit être défini pour chaque répertoire du module.

Exemple :

Modules[modifier | modifier le code]

Un module est défini par un fichier appelé module.ceylon qui doit se trouver à la racine de l'arborescence de packages.

Exemple :

Une fois buildé, les modules Ceylon sont disponibles soit sous forme d'archives .car pour être utilisé sur une JVM, soit sous forme de fichier .js pour être utilisables en Javascript.

Gestion des types de données[modifier | modifier le code]

Structures de contrôle[modifier | modifier le code]

La syntaxe est proche de celle de Java ou de C#. Une petite différence toutefois : Ceylon interdit d'omettre les accolades quand on ne veut exécuter qu'une seule instruction, les blocs devant être exécutés dans les structures de contrôle doivent obligatoirement être délimités par des accolades.

Conditions[modifier | modifier le code]

  • Condition simple : l'instruction if se comporte exactement comme en C ou en Java :

Exemples :

if (i == 3) {
    faitQuelqueChose();
}

Avec une clause else :

if (i == 2) {
    faitQuelqueChose();
} else {
    faitAutreChose();
}

Malgré le fait qu'il soit interdit d'omettre les accolades pour délimiter le code à exécuter dans chaque cas, il est possible d'enchainer les conditions :

if (i == 3) {
    faitQuelqueChose();
} else if (i == 2) {
    faitAutreChose();
} else {
    faitEncoreAutreChose();
}
  • Liste de cas

Boucles[modifier | modifier le code]

Assertions[modifier | modifier le code]

Gestion des exceptions[modifier | modifier le code]

Fonctions[modifier | modifier le code]

Types paramétrés[modifier | modifier le code]

Polymorphisme sur les opérateurs[modifier | modifier le code]

Métaprogrammation[modifier | modifier le code]

Interopérabilité avec Java et Javascript[modifier | modifier le code]

Commentaires et documentation intégrée[modifier | modifier le code]

En Ceylon, les commentaires s'écrivent exactement comme en Java ou en C++ : Les commentaires sur une seule ligne doivent commencer par la séquence //. Tout le reste de la ligne est alors considéré comme du commentaire. Les commentaires sur plusieurs lignes doivent commencer par /* et se terminer par */. Tout ce qui se trouve entre ces deux séquences sera alors considéré comme du commentaire.

Exemples :

/* Ceci est un commentaire */
 
/* Un autre
commentaire */
 
// Ceci est également un commentaire
 
String texte; // Encore un commentaire

Outils[modifier | modifier le code]

Pour développer en Ceylon, plusieurs outils sont mis à disposition : Un IDE basé sur Eclipse composé d'un ensemble de plugins, un pack d'outils en ligne de commande basés sur Ant[6], comprenant notamment des compilateurs et des lanceurs pour Java et Javascript et un outil de documentation, un SDK comprenant toutes les librairies Ceylon, ainsi qu'un référentiel de modules permettant de récupérer les modules désirés et de publier les siens, appelé Ceylon Herd.

Il existe aussi un projet de portage des outils pour Eclipse dans l'environnement IntelliJ.

Références[modifier | modifier le code]

Voir aussi[modifier | modifier le code]

Liens externes[modifier | modifier le code]