L’informatique est une science jeune et en perpétuelle évolution. Même si ses fondamentaux n’ont pas changé depuis ses balbutiements, des concepts nouveaux, des langages, des technologies et bien d’autres concepts apparaissent et disparaissent au fil du temps.
Yet another language
Un des principaux axes dans lesquels l’informatique évolue au fil du temps est sans conteste les langages de programmation.
Des principes fondamentaux
Les principaux paradigmes de programmation existent depuis très longtemps (1957 pour le procédural avec Fortran, 1969 pour l’orienté objet avec Smalltalk, 1958 pour le fonctionnel avec Lisp d’après Wikipédia).
Les langages se distinguent également par la façon dont le code qu’ils produisent est exécuté. Certains sont des langages compilés directement en code machine, d’autres nécessitent un interpréteur. Là encore, les concepts principaux existent depuis longtemps. Par exemple, la première machine virtuelle avec compilation à la volée (Just In Time) a été créée en 1980 pour exécuter du Smalltalk.
Les langages sont aussi caractérisés par d’autres critères. On peut évoquer le typage qui peut être statique, dynamique ou inféré mais aussi plus ou moins fort. La syntaxe est également un critère qui compte énormément dans la mesure où elle représente sa partie visible.
L’ensemble de ces axes permet d’envisager des possibilités absolument infinies en terme de diversité. Les langages modernes sont nettement différents de leurs ancêtres même si ils reposent sur des principes identiques. Ils ne sont ni plus ni moins que des assemblages de ces différents concepts de base qui ont gagné en maturité depuis leur création. Ils sont généralement conçus en capitalisant sur leurs grands frères.
Un éternel recommencement
Depuis toujours de nouveaux langages arrivent. Certains sont innovants, d’autre moins. Certains reprennent des concepts qui n’ont pas fonctionné dix ans plus tôt et ont du succès. D’ailleurs, comme partout ailleurs, en informatique il y a des modes qui fluctuent en fonction du temps. Un autre facteur qui évolue (positivement) au cours du temps est la puissance des machines que nous utilisons. Les nouveaux langages qui arrivent suivent plus ou moins ces tendances et il faut tomber au bon moment pour avoir le succès escompté.
Si t’as pas créé ton langage t’as raté ta vie de développeur.
Des langages, il en existe une quantité incroyable. A tel point d’ailleurs que des fois je me demande un peu l’intérêt de créer encore et encore des langages. Il y a bien entendu un aspect pédagogique qui est très important, concevoir et implémenter un langage n’est pas une expérience commune. Mais beaucoup d’entre eux sont voués à l’échec avant même de naître, ne serait-ce qu’à cause de la quantité astronomique de travail que ce genre d’aventure engendre. Pour devenir populaire, un langage doit déjà être bien conçu, mais également documenté, accompagné d’outils. Cela demande aussi une communauté qui permette aux utilisateurs de s’entraider.
La multiplication des langages a tendance à diviser les efforts. Ne vaudrait-il pas mieux s’allier et unir les efforts pour renforcer encore et outiller les langages qui ont le vent en poupe ? Parallèlement à cela, c’est aussi une façon d’innover. Tenter des choses qui paraissent folles conduit parfois à des formidables évolutions technologiques. Dans le tas il y en a quelques uns qui tirent leur épingle du jeu, les autres tombent à l’abandon.
La quête du langage idéal
La diversité des langages qui existe aujourd’hui semble montrer que nous ne partageons pas tous la même définition du langage parfait. Certains langages sont très spécialisés et donc très adaptés au domaine qu’ils visent. D’autres langages se veulent plus généralistes.
Pour ce qui me concerne, je commence à avoir une idée précise des caractéristiques du langage qui serait pour moi idéal. Déjà, pour commencer, je précise que le cadre visé est celui d’un projet moderne (avec forcément du web donc) développé par une équipe plus ou moins grosse avec du roulement (des arrivées, des départs), le tout sur une durée plus ou moins longue. En gros, un projet qui représente le quotidien d’une très grande partie d’entre nous.
Les maîtres mots sont alors simplicité et lisibilité. Je rappelle d’ailleurs que nous passons beaucoup plus de temps à lire du code qu’à en écrire. Les caractéristiques nécessaires sont alors assez simples à décrire :
- Typage statique et fort
- Une syntaxe assez fermée qui ne propose qu’un seul moyen d’exprimer chaque concept
- Supporté par de nombreux outils (dont un IDE et un bon outil de build)
- Accompagné d’un large écosystème de bibliothèques (permettant d’éviter la tentation de tout refaire soi-même)
Tout ceci doit permettre de faire en sorte qu’un développeur ayant les bases fondamentales de la programmation puisse comprendre spontanément n’importe quelle partie du code.
L’écosystème Java n’est pas en reste
Dans le monde Java aussi des nouveaux langages arrivent régulièrement. Cela tend d’ailleurs à prouver que la plate-forme Java est une base très intéressante pour les créateurs de langages, notamment grâce à la JVM qui se veut aussi indépendante que possible du langage Java en lui-même. Il est ainsi possible de créer son propre langage pourvu que sa compilation génère du byte-code Java.
Parmi les langages qui sont en train de monter, nombreux sont ceux qui ont un pied dans le monde Java. Scala et Groovy sont de plus en plus populaires. Dans le registre de la programmation fonctionnelle, Clojure semble également avoir la côte. Une des exceptions est peut-être Go qui n’a aucun lien avec Java et, malgré son jeune âge (2009), est déjà populaire.
Pour caricaturer un peu Groovy, c’est un peu Java avec plein de trucs cools supplémentaires mais sans une des plus grandes forces de Java, son typage statique. Comme j’ai déjà pu l’exprimer, je ne crois pas aux langages dynamiques sur un gros projet, et Groovy n’échappe pas à la règle. Malgré tout, l’existence d’un langage de script dans le monde Java est très intéressante, notamment pour le prototypage et l’outillage, et Gradle en est un très bon exemple.
Pour ce qui concerne Scala, j’ai un avis beaucoup plus négatif. Même si pour le coup l’accent est mis sur le typage statique, beaucoup de choses me dérangent. On dirait un langage conçu pour écrire de la littérature. Il permet d’écrire du code très court et visuel (opérateurs et sucres syntaxiques), avec un aspect poétique qui nécessite de lire entre les lignes, de laisser libre cours à son imagination. C’est en tout cas ce que j’ai ressenti à chaque fois que j’ai été confronté à du Scala. Je ne vois pas comment on peut travailler sur un projet avec plusieurs développeurs avec un langage aussi élitiste. Il va, comme C++, à l’encontre d’une des principales caractéristiques d’un bon langage, la simplicité.
D’autres langages plus marginaux comme Golo et Kotlin en sont à leurs balbutiements. Mais parmi tous ces langages basés sur la JVM, il y en un a que je n’ai pas cité et qui retient particulièrement mon attention, il s’agit de Ceylon.
Ceylon, le langage idéal ?
Le concept
Ceylon a été lancé en 2011. Il est open-source et supporté par Red Hat qui dédie une petite équipe à son développement. La première version stable Ceylon 1.0.0 a été publiée en novembre 2013.
Comme l’indique le site du langage, Ceylon est un langage conçu pour écrire de gros logiciels en équipe. Ses objectifs sont clairs :
- Sécurité et robustesse grâce à son typage fort et statique
- Lisible grâce à une syntaxe très fermée qui n’offre pas de nombreux moyens différents d’exprimer une même chose
- Nativement modulaire avec le support par exemple de la gestion de dépendance
- Accompagné d’un gros écosystème d’outils, sa syntaxe et son typage augmentant significativement le champ de possibilités accessible aux outils
Ceylon a la particularité d’être basé sur la JVM, il est donc naturellement interopérable avec Java. Mais son compilateur est également capable de générer du code Javascript, ce qui permet de coder à la fois le serveur et le client d’une application web dans le même langage. Plutôt intéressant comme concept !
Le best-of de Ceylon
Ceylon met un fort accent sur la sécurité du code en détectant le plus de problèmes possibles dès la compilation. Ceci est permis par son système de typage qui est statique et fort. Il est également plus puissant que celui de Java.
Il permet entre autres d’éviter intégralement la NullPointerException qui est malheureusement si célèbre en Java. En effet, on ne peut pas faire de pointeur nul en Ceylon. Pour autant, on peut signifier qu’une valeur n’existe pas. Il existe un type Null avec une seule instance qui est une constante. Les union-types permettent d’exprimer le fait qu’une valeur est d’un type ou vide. Un sucre syntaxique permet d’écrire String? pour signifier que la valeur est soit de type String soit nulle. Le compilateur exige alors de vérifier le type de la variable avant de permettre l’utilisation de concepts qui sont spécifiques à un type. De manière plus générale, le compilateur est capable de faire du raffinement de type grâce à l’opérateur is qui est un peu l’équivalent du instanceof de Java, ce qui permet de se passer complètement du cast et de la ClassCastException.
Les types génériques de Ceylon sont également plus puissants et plus sûrs que ceux de Java. Qui n’a jamais bataillé en Java en essayant de convertir une liste d’éléments d’un certain type en une liste d’éléments d’un type parent ? Ceylon adresse proprement les problématiques de covariance et de contravariance de manière un peu similaire à C#.
Ceylon intègre également de nombreux concepts modernes. Les variables sont par défaut constantes (ce qui pousse à faire des objets immuables). Il supporte les compréhensions dans un style similaire à Python, ce qui permet de travailler avec des ensembles de manière très intuitive et expressive. Il supporte également les paramètres nommés, qui, couplés à une syntaxe alternative pour construire des objets, permet de faire de beaux DSL. Il supporte aussi nativement la programmation fonctionnelle.
Il est nativement modulaire. Le mécanisme de module permet de distinguer le code qui doit être exposé à l’extérieur (API), de ce qui ne doit pas être partagé (implémentation). Il supporte également nativement les dépendances.
Pour forcer l’homogénéité du code, le compilateur est également strict sur le respect des conventions d’écriture. Il ne tolérera pas par exemple un type commençant par une minuscule ou une fonction avec une majuscule.
Une sorte de Java amélioré
J’avais déjà expliqué pourquoi j’aime Java. Mais même si aujourd’hui Java est mon favori dans la catégorie des langages matures, il n’est pas pour autant exempt de défauts. Et bien que la version 8 l’ait énormément modernisé, certains de ses défauts sont condamnés à l’accompagner jusqu’à la fin de sa vie compte-tenu de l’obligation de la rétrocompatibilité qui est un des principes fondateurs du langage.
Ce que j’apprécie dans Ceylon c’est qu’il dérive de Java dans le sens où il reprend tous les concepts de Java qui ont contribué à sa popularité au fil du temps, mais il s’attaque également aux points sur lesquels Java est clairement perfectible.
La visite guidée de Ceylon permet de découvrir des concepts peu courants dans les langages populaires actuels et qui adressent des limitations auxquelles nous sommes confrontés plus ou moins au quotidien et que nous considérons souvent comme des fatalités. Je pense par exemple à la NullPointerException. Parfois-même nous ne sommes même pas conscients de certaines limitations, et simplement le fait de découvrir que Ceylon permet d’aller au delà les met en lumière.
Quoi qu’il en soit, compte-tenu des concepts qui sont mis en avant dans ce langage, on se rend compte que ses concepteurs ont une grande expérience dans le développement d’applications en équipe, et en particulier une très bonne connaissance de Java et de ses limitations. Ils ont su prendre du recul et apporter des solutions qui à mon idée forment un ensemble mature et robuste.
Un candidat à la succession de Java
La domination de Java se terminera forcément un jour ou l’autre. Mais Duke se défend bien malgré les nombreuses attaques qu’il subit. L’arrivée de Java 8 peut même être vue comme une contre-attaque visant à mettre tout le monde d’accord et à réunifier l’ensemble de l’écosystème Java qui s’était un peu déchiré. Java 8 est en train d’offrir une seconde jeunesse au langage et va sans doute prolonger significativement son espérance de vie. Pas sûr que Java soit prêt à tirer sa révérence…
Si toutefois on devait trouver un remplaçant à Java aujourd’hui, aucun des langages les plus populaires ne semble sortir franchement du lot pour lui succéder. Je considère que Ceylon est le meilleur candidat à sa succession dans la mesure où il remplit pour moi plus ou moins l’ensemble des critères du langage idéal. Mais pour prétendre à ce titre, il doit encore gagner en maturité et la route est encore très longue. Pour devenir populaire, un langage doit être accompagné d’un écosystème solide, aussi bien en terme d’outillage que de briques logicielles. Et tout cela ne se fait pas en un jour. Cela ne peut se faire que si il y a une adhésion massive des développeurs.
J’avais exprimé mon avis sur Python, notamment tous les atouts que je lui voyais malgré un typage dynamique très pénalisant. Ceylon représente un peu la modernité de Python accompagnée d’une sécurité assurée par son système de typage.
L’image d’en-tête provient de Flickr et représente les derniers lacets du col d’Izoard.
Merci pour cet article !
Concernant le langage Groovy, je pense qu’il ne faut pas le voir comme un remplaçant de Java (bien que l’on puisse écrire une application complète en Groovy), mais comme un compagnon idéal pour toutes ses qualités dynamiques et sucres syntaxiques.
De plus, j’aimerais aussi rappeler que du code Groovy peut être vérifié et compilé statiquement :
« Groovy… provides the ability to statically type check and statically compile your code for robustness and performance » (voir l’indroduction de Groovy Language Documentation).
Merci pour ce retour.
Pour ce qui concerne Groovy, j’avais bien pris la précaution de préciser que mon discours est volontairement caricatural.
Je connais l’existence de l’annotation TypeChecked, mais c’est dommage d’avoir à demander explicitement la vérification statique. Ceylon propose l’approche inverse : par défaut le typage est statique mais on peut ponctuellement passer en typage dynamique. Elle me semble plus adaptée si on veut un code qui soit majoritairement typé statiquement.
Quoi qu’il en soit on est d’accord sur le fait que Groovy n’a pas vocation à remplacer Java mais plutôt à l’enrichir ou le compléter.