Accueil🇫🇷Chercher

XL (langage)

XL, dont les lettres proviennent de eXtensible Language, est un langage de programmation, basé sur la programmation par concepts[1], développé depuis 2000 par Christophe de Dinechin.

XL (eXtensible Language)
Date de première version 2000
Paradigmes Programmation impérative
DĂ©veloppeur Christophe de Dinechin
Dernière version 0.1 (2010)
Typage Fort
Influencé par Ada, C++
Système d'exploitation Type Unix
Licence GPL
Site web XLR

XL offre la possibilité de modifier et programmer la syntaxe et la sémantique du langage. Des plugins compilés peuvent être utilisés pour ajouter de nouvelles fonctionnalités au langage. On peut par exemple noter un ensemble de plugins permettant la mis en œuvre d'un langage impératif. Les utilisateurs peuvent écrire eux-mêmes leurs propres plugins pour permettre l'utilisation de syntaxe spécifiques, par exemple pour la dérivée, qui pourront être utilisés de la même manière que les fonctionnalités originales.

Langage

XL est défini en quatre niveaux différents :

  • XL0 dĂ©finit comment le texte entrĂ© est converti en un arbre syntaxique
  • XL1 dĂ©finit un langage de base avec des possibilitĂ©s comparables au c++
  • XL2 dĂ©finit la bibliothèque standard qui inclut les types de donnĂ©es communs ainsi que les opĂ©rateurs
  • XLR dĂ©finit un Moteur d'exĂ©cution dynamique pour XL basĂ© sur XL0

XL n'a ni type primitif ni mot-clé. Tous les opérateurs et les types de données, tels que les entiers ou les additions, sont définis dans la bibliothèque standard XL2. XL1 est portable dans différents environnements d'exécution. Ce qui n'est pas garanti pour XL2 qui n'offre pas de tels garanties : si un processeur particulier n'implémente pas la multiplication en virgule flottante, la définition de l'opérateur correspondant peut être manquante de la bibliothèque standard, et l'utilisation de cette fonctionnalité peut générer une erreur de compilation.

En XL, le programme Hello World peut s'Ă©crire ainsi :

 use XL.TEXT_IO
 WriteLn "Hello World"

Une manière plus convenable pour des programmes plus importants serait :

 import IO = XL.TEXT_IO
 IO.WriteLn "Hello World"

Une implémentation par récurrence de la fonction factorielle :

 0! → 1
 N! → N * (N-1)!

Syntaxe

La syntaxe est définie au niveau XL0. La phase XL0 du compilateur peut être configurée en utilisant un fichier de description de la syntaxe, où sont définies des propriétés telles que la représentation du texte et les priorités des opérateurs. Un fichier de syntaxe basique définit les notations mathématiques communes tel que + pour l'addition, ainsi que la priorité des opérations.

L'arbre syntaxique est composé de 7 types de nœuds : 4 types de feuilles (entier, réel, texte et symbole) et 3 types de nœuds internes (infixe, préfixe et bloc).

  • un nĹ“ud entier est la reprĂ©sentation littĂ©rale d'un entier, comme 2. Le signe # peut indiquer une base diffĂ©rente de 10, par exemple (2#1001). Un caractère soulignĂ© (ou underscore) comme sĂ©parateur peut aider la lecture, par exemple 1_000_000.
  • un nĹ“ud rĂ©el reprĂ©sente un nombre non entier, comme 2.5. Les notations de base et les sĂ©parateurs peuvent ĂŞtre utilisĂ©s de la mĂŞme façon pour les entiers, par exemple 16#F.FFF#E-10 est une reprĂ©sentation littĂ©rale valide d'un rĂ©el.
  • un nĹ“ud texte reprĂ©sente un contenu textuel. Il est classiquement entourĂ© par un guillemet simple ou double, comme "Salut" ou 'a', mais le fichier syntaxique peut ĂŞtre utilisĂ© pour ajouter d'autres sĂ©parateurs, dont ceux dĂ©diĂ©s aux textes Ă  lignes multiples.
  • un nĹ“ud symbole reprĂ©sente un nom ou un opĂ©rateur. Un nom est une sĂ©quence de caractères alpha-numĂ©riques commençant par une lettre, par exemple Salut. XL0 prĂ©serve la casse, mais XL1 ignore la casse et le caractère soulignĂ© ce qui fait que MonsieurDupont et Monsieur_Dupont sont le mĂŞme nom. Un symbole est une sĂ©quence de caractères non alpha-numĂ©riques, par exemple * ou =/=.
  • un nĹ“ud infixe reprĂ©sente deux nĹ“uds liĂ©s par une notation infixĂ©e, par exemple A+1 ou 2 and 3. En particulier, un nĹ“ud infixe combinĂ© Ă  un infixe "nouvelle-ligne" permet de sĂ©parer deux lignes.
  • un nĹ“ud prĂ©fixe reprĂ©sente deux nĹ“uds consĂ©cutifs, par exemple Write "Salut". Ceci est aussi utilisĂ© dans la notation postfixe, par exemple 3! ou Open?.
  • un nĹ“ud bloc reprĂ©sente un nĹ“ud entourĂ© par des symboles isolants, par exemple (A) ou [Index]. Une indentation est reprĂ©sentĂ©e en interne par un nĹ“ud bloc.

Avec le fichier de syntaxe par défaut, le code suivant est valide pour XL0, indépendamment de la sémantique :

A = B + "Salut"

Il est décomposé en :

infix("=",
      symbol("A"),
      infix("+",
            symbol("B"), text("Salut")))

SĂ©mantique de XL1

Le niveau XL1 est défini comme une séquence d'opérations sur l'arbre syntaxique du niveau XL0. Ces opérations sont effectuées par divers plugins du compilateur qui sont appelés suivant la forme de l'arbre syntaxique.

Des constructions particulières, translate et translation, sont fournies par un plugin destiné à faciliter l'écriture d'autres plugins. La construction quote génère un arbre syntaxique. Voici comment ces constructions peuvent être utilisées pour implémenter un plugin nommé ZeroRemoval, qui supprime les additions et multiplications par zéro :

translation ZeroRemoval
  when
    'X' + 0
  then
    return X
  when
    'X' * 0
  then
    return parse_tree(0)

Un plugin peut être invoqué sur un fichier complet à partir de la ligne de commande, ou plus localement dans le source du code en utilisant la notation pragma, comme ici :

X := {Differentiate} d(sin(omega * T) * exp(-T/T0)) / dT

Le niveau XL1 contient un grand ensemble de plugins, notamment XLSemantics qui donne les abstractions communes telles que fonction, type de données et déclaration de variable et définition, et aussi les ordres de base de la programmation structurée que sont les boucles et les conditions.

Système de typage

XL1 contrôle le type statique, avec des possibilités de programmation générique qui vont au-delà de celles de C++ ou Ada. Les types comme les tableaux ou les pointeurs, qui sont des types primitifs en C++, sont déclarés dans une bibliothèque dans XL. Par exemple, le type d'un tableau d'une dimension peut être défini par :

generic [Item : type; Size : integer] type array

Un type générique validé est un type générique où une condition indique comment le type peut être utilisé. De tels types ne doivent pas avoir de paramètres génériques. Par exemple, on peut déclarer un type comme ordered (ordonné) si un opérateur inférieur est présent :

// Un type est ordonné en présence d'un opérateur inférieur
generic type ordered if
  A, B : ordered
  Test : boolean := A < B

Il est alors possible de déclarer une fonction qui est implicitement générique puisque le type ordered est lui-même ordonné.

// Function générique pour au moins un élément
function Min(X : ordered) return ordered is
  return X

Ceci s'applique aussi aux types génériques qui ont des paramètres, comme array. Une fonction calculant la somme des éléments dans un tableau peut s'écrire :

function Sum(A : array) return array.Item is
  for I in 0..array.Size-1 loop
    result += A[I]

Type protégé de liste de variable d'arguments

Les fonctions peuvent être surchargées. Une fonction peut être déclarée avec un nombre variable d'arguments grâce au mot other dans la liste des paramètres. Dans une telle fonction, other permet de passer un nombre variable d'arguments à une autre fonction :

// Fonction générique pour le minimum de N éléments
function Min(X : ordered;…) return ordered is
  result := Min(…)
  if X < result then
    result := X

Quand ce genre de fonction est appelée, le compilateur invoque les fonctions de manière récursive pour correspondre à la liste :

// Exemple d'utilisation de la fonction Min précédente
X : real := Min(1.3, 2.56, 7.21)
Y : integer := Min(1, 3, 6, 7, 1, 2)

Réduction d'expression (surcharge d'opérateur)

Les opérateurs peuvent être définis en utilisant la forme written de déclaration de fonction. Voici un code qui déclare l'addition d'entiers :

function Add(X, Y: integer) return integer written X+Y

De telles formes écrites peuvent avoir plus de deux paramètres. Par exemple, une transformation de matrice linéaire peut s'écrire :

function Linear(A, B, C : matrix) return matrix written A+B*C

Une forme écrite peut utiliser des constantes, et ce type de forme est plus spécialisée que sans constantes. Par exemple :

function Equal(A, B : matrix) return boolean written A=B
function IsNull(A : matrix) return boolean written A=0
function IsUnity(A : matrix) return boolean written A=1

Ce mécanisme est utilisé pour décrire tous les opérateurs de base. Une expression est progressivement réduite à des appels utilisant des formes écrites. Pour cette raison, ce mécanisme est appelé réduction d'expression plutôt que surcharge d'opérateur.

Itérateurs

Les itérateurs de XL permettent de programmer à la fois des générateurs et des itérateurs.

import IO = XL.UI.CONSOLE
iterator IntegerIterator (var out Counter : integer; Low, High : integer) written Counter in Low..High is
    Counter := Low
    while Counter <= High loop
        yield
        Counter += 1
// I doit être déclaré, car indiqué comme 'var out' dans l'itérateur
// Une déclaration implicite de I comme entier est alors faite ici
for I in 1..5 loop
   IO.WriteLn "I=", I

SĂ©mantique de XLR

XLR est un langage dynamique, conçu dès l'origine comme un exécutant (back-end) pour le compilateur XL1 (d'où le nom, qui représente le runtime de XL). Il partage la syntaxe de base XL0 avec XL1, mais son comportement est plus proche de celui d'un langage fonctionnel, même si XL1 est censé ressembler plus à un langage impératif. XLR n'a pratiquement qu'un seul opérateur de construction, "→", qui indique une réécriture. La notation à gauche de la notation de la réécriture est transformée en notation à droite de la réécriture.

Ce mécanisme est utilisé pour implémenter les notations standards :

 si vrai alors PartieVraie sinon PartieFausse → PartieVraie
 si faux alors PartieVraie sinon PartieFausse → PartieFausse

État du développement et historique

Le design de XL a commencĂ© aux alentours de 1992, sous le nom LX (Langage eXpĂ©rimental). Le projet a Ă©tĂ© mis dans le domaine du logiciel libre en 2000, dans le cadre du projet « Mozart » qui visait Ă  fournir des capacitĂ©s de mĂ©taprogrammation multi-langage. Les premiers compilateurs Ă©taient Ă©crits en C++, mais cela rendait l'Ă©criture d'extensions de compilateurs compliquĂ©e, car C++ ne permettait pas d'offrir le niveau d'abstraction voulu (par exemple un Ă©quivalent de translate). Les aspects multi-langage rendaient les arbres syntaxiques difficile Ă  manipuler en respectant la sĂ©mantique de chaque langage.

Une réécriture complète du compilateur a commencé en 2003, abandonnant l'idée de support multi-langage qui avait montré ses limites, et focalisant sur la facilité d'écriture des extensions. L'arbre syntaxique abstrait a été réduit à sept types de nœud seulement pour représenter tous les programmes. Ce nouveau compilateur s'est auto-compilé en 2004 (bien qu'avec des capacités réduites et une dépendance à C++ dans le code généré). Depuis, tout le développement se fait en XL.

En 2007, le langage offre un grand nombre de fonctionnalités avancées, mais manque encore d'une bibliothèque fonctionnelle.

Prédécesseurs

XL a été inspiré par un grand nombre d'autres langages. Dans l'ordre alphabétique :

  • Ada a inspirĂ© quelques fonctionnements appliquĂ©s sur la totalitĂ© d'un programme, comme la gestion d'exception, les tâches, la portabilitĂ©.
  • Basic, principalement dans les versions modernes qui s'affranchissent des numĂ©ros de lignes et permettent la programmation structurĂ©e, a montrĂ© combien un langage de programmation peut ĂŞtre simple. Basic est un des premiers langages modernes ne nĂ©cessitant pas la prĂ©sence de parenthèse autour des appels de routine.
  • C a servi comme standard pour l'exĂ©cution (runtime) et le niveau machine. XL ne tourne pas sur une machine virtuelle.
  • C++ par ses bibliothèques de modèles standards a montrĂ© le besoin d'une bonne implĂ©mentation des types gĂ©nĂ©riques, incluant implicitement les instanciations des gĂ©nĂ©riques (ce qui fait dĂ©faut Ă  Ada).
  • Fortran poursuit et dĂ©passe les performances de C et C++ sur les applications de calcul intensif, aidant l'identification des constructions de langage qui prĂ©viendrait des optimisations utiles.
  • Java dĂ©montre l'importance d'un système de bibliothèques portables. Les conteneurs Java montrent aussi les limitations d'une approche non basĂ©e sur une programmation gĂ©nĂ©rique. L'interfaçage avec le code Java reste un dĂ©fi intĂ©ressant pour XL.
  • L'extensibilitĂ© de Lisp a Ă©tĂ© vue comme un facteur clĂ© de sa survie et de son intĂ©rĂŞt jusqu'Ă  aujourd'hui. Lisp a Ă©tĂ© le premier langage Ă  introduire les fonctionnalitĂ©s de l'orientĂ© objet, mĂŞme s'il a Ă©tĂ© conçu des annĂ©es avant que la programmation orientĂ©e objet ne soit inventĂ©e.
  • Prolog a dĂ©montrĂ© que les paradigmes de programmation alternatifs sont parfois utiles et hautement productifs. Tout a Ă©tĂ© fait pour s'assurer qu'un plugin dans le style de Prolog puisse ĂŞtre Ă©crit pour XL.
  • Visual Basic a montrĂ© comment la reprĂ©sentation de l'arbre d'analyse peut ĂŞtre sĂ©parĂ©e de sa prĂ©sentation visuelle. Peu de gens Ă©ditent des formulaires VB sous forme textuelle. On peut espĂ©rer que les plugins d'Ă©dition XL fourniront un jour des fonctionnalitĂ©s similaires, en manipulant directement l'arbre d'analyse.

Notes et références

  1. (en) Phil Manchester, « Dip into Concept Programming », The Register,‎ (lire en ligne, consulté le )

Liens externes

Cet article est issu de wikipedia. Text licence: CC BY-SA 4.0, Des conditions supplémentaires peuvent s’appliquer aux fichiers multimédias.