Language Oriented Programming

Domain Specific Language

Présentation

Le Domain Specific Language (DSL) est bien un langage de programmation à part entière.
Il instaure une structure, qui correspond à la syntaxe abstraite du programme. Cette structure définit les concepts manipulés et la façon dont ils peuvent être arrangés.
Il propose un éditeur, permettant ainsi d´utiliser une syntaxe concrète, afin d´éditer et restituer les programmes utilisant le DSL.
Il arrête une sémantique qui fixe le comportement du langage, c´est-à-dire comment il doit être interprété et/ou transformé afin de produire du code compréhensible par la machine.

Etant totalement défini par celui qui le crée, le DSL n´a pour ainsi dire pas de limite. Il faut toutefois respecter les trois piliers fondamentaux que sont la structure, l´éditeur et la sémantique, qui identifient un langage de programmation.
Rien n´interdit cependant d´ajouter d´autres caractéristiques qui viendront renforcer le DSL. Il peut donc posséder d´autres aspects, et être caractérisé par des contraintes, des types...

Il existe plusieurs types de représentations des DSL. Chaque DSL, suivant les concepts mis en place mais aussi le domaine auquel il touche, proposera une représentation (via son éditeur) qui sera la plus à même de permettre d´exprimer les modèles conceptuels élaborés mentalement.
On distinque principalement trois types de représentations :

Contexte d´utilisation

Les DSL peuvent être mis en place dans plusieurs environnements. Chacun de ces contexte a ses spécificités et est plus ou moins adapté à ce que souhaite chaque programmeur. Les différents contextes répondent à un besoin différent.

Le premier de ces contexte est l´utilisation en standalone. Dans ce cas, le DSL est appelé directement depuis une action utilisateur, depuis une ligne de commande par exemple. Le DSL est ici utilisé comme un programme à part entière. On reconnaît le shell de Linux, qui permet à tout un chacun d´émettre des commandes, directement interprétées, afin de manipuler un système de gestion de fichiers.

Le DSL peut aussi être vu en tant qu´outil pour un GPL. Pour effectuer des actions spécifiques pour le compte d’une application hôte, le DSL sera manipulé via des instructions ou une API au niveau du GPL. C´est notamment le cas de SQL, qui peut par exemple servir au sein de Java ou encore de C++ avec des librairies. Parfois un interpréteur est utilisé pour faire correspondre le code DSL en code GPL.

Encapsulé dans une application, le DSL permet à un utilisateur d´entrer et d´exécuter du code, ou encore d´exécuter du code généré dynamiquement, voire les deux. Cette technique permet, après avoir par exemple créé un programme à l´aide d´un GPL, d´offrir la possibilité aux utilisateurs de le modeler pour le faire correspondre le plus précisément possible à leurs attentes. Langage de macro des feuilles de calcul est un exemple de ce type de DSL.

Enfin, le DSL peut être implémenté avec un système de programmation par macros puis transformé en GPL, pour être converti à compile-time ou read-time. Cette technique permet de conserver une partie de la simplicité du DSL tout en utilisant les outils du GPL choisi.

Les différents DSL

On peut classer les DSL en plusieurs types. Principalement, on retrouve deux catégories : les DSL dits "internes" et ceux dits "externes". La différence est fondamentale et les atouts variés. Avant de se lancer dans la création d´un DSL, il convient de bien choisir quel type de langage on souhaite mettre en oeuvre. Voici quelques éléments qui peuvent aider à la décision

DSL "interne"

Concept

Le principe ici est de métamorphoser un GPL en DSL. On utilise le langage à but général afin de le spécialiser pour qu´il puisse répondre à nos besoins. On va ainsi tenter de simplifier la programmation en masquant le plus possible les parties "inintéressantes" pour l´expert du domaine. Cette vision des choses semble se rapprocher de la création d´une librairie, mais ce n´est pas totalement vrai. En effet, un DSL interne peut être fait de telle sorte que le GPL soit très effacé, ne laissant la place qu´à des instructions plus haut niveau.

Ses forces

Le DSL interne dispose de la puissance du langage de base. Le GPL étant destiné à pouvoir réaliser tout et n´importe quoi, le DSL peut s´appuyer sur cette capacité pour développer des fonctionnalités très poussées (librairies de gestion de fichiers, de communication réseau...) et les fournir de façon souple au programmeur.
De plus, en créant un DSL interne, on réduit considérablement le coût en outil, et on peut même l´annuler. Puisqu´on va créer le DSL dans un GPL, il est possible de s´aider des outils de manipulation du GPL pour manipuler le DSL.

Sa faiblesse

La principale faiblesse du DSL est qu´il est limité par le langage de base. Bien qu´il puisse en tirer les librairies et autres facilités, il doit aussi cependant souffrir de la maigreur des opérations disponibles, et s´il s´appuie uniquement sur le GPL, il risque d´être bloqué par le manque d´abstraction qu´il offre. On conserve alors la difficulté d´exprimer et de représenter des idées et concepts très haut niveau dans un langage bas niveau.

DSL "externe"

Concept

écrit dans un langage unique, le DSL externe permet la liberté d´utiliser la forme que l´on souhaite. Ainsi, on dispose d´une façon simple d´exprimer et modifier les idées d´un domaine. La seule limite est la nécessité de créer l´outil nécessaire à la traduction du DSL en code exécutable par la machine (ou en code GPL, qui sera ensuite compilé ou interprété).

Ses forces

La liberté d’expression dont fait preuve ce type de DSL est sa grande force. Elle induit un gain de clarté certain mais aussi une grande simplicité d’utilisation. Celui qui manipule le DSL peut rapidement prendre en main les différents concepts proposés puisqu´ils correspondent à des idées qu´il manipule naturellement.

Sa faiblesse

On l´aura compris, la faiblesse des DSL externes est la nécessité de créer ses propres outils. Que ce soit pour traduire le code DSL en code GPL ou directement pour produire du code exécutable depuis le code DSL, il est indispensable de se munir d´outils capables de manipuler le DSL. Cette exigence est lourde et peut être rebutante, ce qui malheureusement peut conduire à éviter l´utilisation d´un DSL alors que la situation serait parfaitement adaptée.

Création d´un DSL

Créer un DSL revient à mettre en place les différents points mentionnés précédemment.

Tout d´abord, on définit une structure. Il faut préciser quels concepts pourront être édités et gérés par le DSL. Le DSL s´applique à un domaine restreint et il faut en fixer les limites mais aussi les capacités. Il s´agit ici d´être précis quant aux concepts proposés et à leurs propriétés. Il faut exprimer clairement et sans ambigüité ce qu´est pour le DSL une voiture, par exemple. On s´intéressera aussi au degré de granularité qu´on souhaite observer; dans le cas de la voiture, on peut simplement la définir en tant que telle, ou créer par la même occasion un concept "conducteur", qui, on le verra après, sera lié à la voiture. L´idée ici est de dire que suivant le domaine dans lequel on veut intervenir (par exemple gestion d´autoroute ou crash test), on ne va pas forcément avoir besoin de faire naître les mêmes concepts (dans notre exemple, le "conducteur" n´est intéressant que dans le cas du crash test).

Ensuite, il faut créer un éditeur. C´est ce programme qui va permettre de manipuler le DSL. Il pourra sauvegarder du code DSL, le modifier... Puisqu´il devra agir directement sur ses différentes composantes, c´est aussi à lui que revient la tâche de déterminer les relations permises entre les différents concepts. Ils pourront être liés ou n´avoir aucune connexion, ou encore des communications complexes. C´est l´éditeur qui devra mettre en place l´interface permettant de gérer ces concepts et ces liens. Suivant le type de DSL, il peut être graphique, textuel...

La dernière étape est la mise en place de la sémantique. On suppose que lorsque cet outil sera nécessaire, le code en DSL sera déjà créé. Il faudra alors choisir comment les concepts seront expliqués à l´ordinateur, et donc définir le comportement du DSL. Pour ce faire, on crée des règles de sémantique, mais aussi un programme dont le rôle est de traduire ou de générer du code.
Dans le cas d´un générateur, on veut transformer le code en DSL en instructions compréhensibles par la machine, et donc très bas niveau.
Dans le cas du traducteur, on cherche à translater les instructions exprimées dans le DSL vers un langage cible. C´est alors grâce aux outils de ce langage (vraisemblablement un GPL) que l´on va générer le code compréhensible par la machine.

Outils

Afin de programmer LOP, on peut avoir recours à différents outils qui simplifient la création, la réutilisation et la modification des DSL. Ces outils ont pour but d´aider le progammeur à créer le DSL et ce qui va avec. On peut notamment citer les suivants :

Exemples de DSL

Pour finir, voici quelques exemples de DSL qui existent et que vous avez peut-être déjà croisé !

SQL

Ce DSL est destiné à la gestion de bases de données. Il propose l´utilisation de texte afin d´exprimer des notions de tables, tuples et autres jointures. A consommer avec modération, sauf pour les experts en base de données !

			
SELECT Personnes.Nom, Personnes.Prénom FROM Personnes WHERE (((Personnes.Nom) Like "c*"));

Shell

Le but ici est de manipuler des systèmes de fichiers. A l´aide de commandes simples, l´utilisateur a accès à des informations sur les fichiers, il peut en créer, en déplacer...

			if test -f $1
			then
				file $1
			else
				echo " le fichier n´existe pas "
			fi

			if grep jean personnel
			then
				echo jean >> disponible
			elif grep pierre personnel
				then
					echo pierre >>  disponible
				else
					echo vide >>  disponible
			fi
			

Persistence Of Vision (POV)

POV s´attaque à un domaine plus artistique car il propose de modéliser des objets en 3 dimensions en les exprimant dans un DSL bien à lui, proche cependant de la syntaxe du C. Le ray-tracing réalisé est de bonne qualité.

			
sphere {0,1 pigment {green 1}} light_source {<-5,8,-9> rgb 1} camera {location -3*z look_at 0}

Csound

Créer des échantillons sonores est le rôle de ce DSL. A manipuler avec précaution : oreilles sensibles, s´abstenir !

			f 1  0 4096 10   1    
			f 2  0 4096 10   1  .5 .333 .25 .2 .166 .142 .125 .111 .1 .09 .083 .076 .071 .066 .062
			f 3  0 4097 20   2  1
			f 4  0 0    1   "sing.aif" 0 4 0


			;inst	start	duration
			i 101		0		3
			i 102		4		3
			i 103  		8       3
			i 104    	12      3
			i 105     	16      3
			i 106     	20      2.3
			

Et pourquoi pas...

On peut également imaginer un DSL qui gère les salaires, un DSL de simulation de combat... Les possibilités sont infinies !