Dites non aux DSL


Un Domain Specific Language est un langage créé pour une tache très particulière. CSS, HTML et SQL sont des bons exemples de DSL populaires. Moins connus: GraphQL, QML, Less, Latex, XPath, Graphviz… Les plus connus sont encore là car ils sont utiles, alors créer le vôtre pourrait être tentant.

Suite à ce tuto sur la fabrication d’un DSL en Python, je réalise que quelques personnes recommandent encore de créer des DSL.

Il faut absolument que je vous empêche de commettre cette erreur irréparable !

Une API n’est pas un DSL

Ruby, qui a des parenthèses optionnelles et la capacité d’intercepter les accès d’attributs à la volée, a lancé la mode du mot DSL à tout va. Sauf que la plupart des DSL en Ruby n’en sont pas. Ce sont juste des API écrites en Ruby.

You keep using that world, I don't think it means what you think it means

You killed my project, prepare to die

Enchaîner les méthodes et opérateurs overloadés dans un langage populaire n’est pas utiliser un DSL. foo.bar().baz() n’est PAS un DSL si ça tourne dans la VM du langage. Quel que soit l’enrobage syntaxique qu’on a rajouté.

Un format de sérialisation générique n’est pas un DSL: XML et YAML n’en sont pas, contrairement à ce qu’on peut lire. Car ils sont généralistes, et donc pas “domain specific” par nature.

Par contre on peut écrire un DSL en JSON, XML ou YAML, et il en existe d’ailleurs pas mal. MathML et SVG sont des exemples de DSL écrits en XML.

Ne créez jamais un DSL

Pourquoi avez vous besoin d’un nouveau langage ? Il existe des centaines de langages et encore plus de formats de sérialisation. Aucun d’entre eux ne peut répondre à votre besoin ? Vraiment ? Vous avez tout testé pendant un mois ?

The world is the problem, the atomic bombs the answer

Choisir le bon outil, Civ style

Créer un DSL , donc un nouveau langage, implique vous avez besoin:

  • d’informations dessus: docs, standards et tutos…
  • d’outils : UI, générateurs, wrapper pour le scripting, coloration syntaxique, snippets, linters, checkers, debuggers…
  • un support du DSL : garantir qu’on pourra le lire, écrire et manipuler dans 5 ans. Pouvoir fournir de nouveaux outils si le besoin évolue. Pouvoir faire évoluer le standard si (pardon “quand”) il se révélera limité. Répondre aux questions des utilisateurs. Fournir des messages d’erreurs et procédures pour résoudre les problèmes. Avoir un bug tracker.

Et il faut tenir tout ça à jour.

Ah. Ah. Ah.

Personne ne le fait jamais, ce qui fait de l’usage de la plupart des DSL un enfer, sans parler de la maintenance des projets qui l’utilisent sur le long terme. Mais les créateurs de DSL s’en effeuillent amoureusement les génitoires car ils seront dans une nouvelle boîte quand ça arrivera. Eux ils se sont bien amusés à créer un parseur pour le fun. D’ailleurs ça fait classe sur le CV.

Fuck everything

Réponse standardisée aux propositions de DSL. Aussi valable pour l’introduction d’une nouvelle stack JavaScript

Créez une API

Votre langage de prédilection est turing complet. Il est donc capable de gérer ce que fait le DSL. Libérez l’anus de cette mouche et traitez votre problème avec un langage supporté, éprouvé, avec un large écosystème et qui résout déjà tout un tas de problèmes.

Ce qu’il vous faut, c’est faire une belle API, pour rendre la tache agréable:

  • Créez des méthodes biens découplées, de l’injection de dépendance et un système d’events.
  • Faites des wrappers plus haut niveau, et des factories pour les cas courants.
  • Utilisez le sucre syntaxique de votre langage pour rendre tout ça tout beau (ex: __getitem__, __enter__, @decorateur, etc. pour python).
Rayon bien rangé

Avec une belle présentation, un truc standard ennuyeux devient soudainement très attractif

Si créer une API n’aide pas assez, par exemple vous faites un outil avec un langage haut niveau et avez besoin d’un langage haut niveau pour le scripting ou la configuration, embarquez un langage haut niveau connu. Par exemple Lua ou Python. Ne faites pas comme varnish ou nginx qui ont des fichiers de configuration dans un langage imbitable, indébuggable et mal documenté.

Quelques bonnes raisons de créer un DSL

Allez, il ne faut jamais dire jamais, et comme toujours en informatique, il y a parfois une bonne raison de faire quelque chose. Voici donc la liste des RARES cas où écrire un DSL a du sens:

  • Vous avez un jeu de règles métier très complexe et des non informaticiens doivent pouvoir les composer. Et une UI ne ferait pas l’affaire pour une raison qui m’échappe. Et vous ne pouvez pas former les non informaticiens parce que fuck you. Les langages de templates types jinja sont dans cette catégorie.
  • Vous avez un jeu de règles métier très complexe, vous voulez pouvoir les serialiser (pour les sauver dans un fichier ou une base de données ou les transmettre à travers le réseau par exemple) et la sérialisation doit pouvoir être accessible depuis plusieurs langages incompatibles (donc pas de dump mémoire, de pickle, etc). Les langages de requêtes comme GraphQL en font partie.
  • Vous créez un langage pour remplacer un autre DSL. Par exemple Sass pour le CSS.
  • Vous voulez des instructions logiques mais sécurisées pour autoriser une source en laquelle vous n’avez pas confiance à manipuler vos données. Et vous ne pouvez pas mettre une couche d’abstraction (ou c’est la couche d’abstraction) type Web API, RPC ou autre et ça va, maintenant, TG, c’est mon projet. Tous les formats des sérialisations pour le RPC justement répondent à ce problème.

Mais dans tous ces cas, ne faites un DSL que si:

  • Une bonne UI n’est pas possible pas pour créer les règles et il faut les sérialiser.
  • Il n’existe pas déjà un standard existant.
  • Vous êtes certains de fournir des outils pour manipuler le DSL.
  • Vous êtes certains de documenter, tester et maintenir le DSL.
  • J’ai dit certains de documenter, tester et maintenir votre DSL. Arrêtez de mentir: vous ne le ferez pas.
  • Lâchez ce DSL tout de suite ! Vous êtes dans une start-up. Vous n’allez jamais faire tout ça. Oust !
Special snowflake award

“Mais moi c’est pas pareil”, le hello word du DSL pour prendre des mauvaises décisions dans la vie

15 thoughts on “Dites non aux DSL

  • François

    “Eux il se sont bien amusé a créé ” -> ouch :)

    Pour latex, ca te semble si mal que ça ? Parce que Tex, c’est indigeste quand même et latex, ça passe. rest, mdwn etc ne donnent pas autant de fonctionnalités.

  • Cdk29

    Cython n’est pas un DSL (je crois ?) mais cet article m’y a fait très fortement penser :-)

  • Sam Post author

    @François : Tous les DSL populaires le sont parce qu’ils sont utiles. Latex est populaire, bien documenté, supporté et outillé. L’article dénonce la création de DSL maisons.

  • Nioub

    “un DSL: XLM et YML” => “un DSL: XML et YML”

    “ex: getiem” => “ex: getitem

    et maintenant TG, c’est mon DSL !

  • yves astier

    Salut, comme d’habitude un article intéressant par contre je ne suis pas d’accord pour Sass qui est a mon avis vient plus comme un plug (remarquez le choix magnifique de ce mot dans le ton du site ;) ) car il crache du css. D’ailleurs pour prendre l’anal-ogie (on reste dans le thème) des dérivés du XML, ce sont certes des spécifiques à un domaine mais il n’en reste pas point dérivé de XML qui voit son usage pour du spécifique (d’ailleurs ce n’est pas pour rien qu’on met ce format en concurrence avec du json ou d’autres formats d’échange).

    Après peut être que c’est la définition du Dsl qui n’est pas clair?

  • lucas

    Je suis très fan du special snowflake award. Je le ressortirais à l’occasion !

    @yves astier

    Un DSL de manière formelle, c’est un langage (souvent limité tant en expressivité que dans son environnement) permet de décrire un modèle qui sera utilisable par un autre programme (généralement un GPL). Sass est dans ce sens bien un DSL, puisqu’il est compilé vers un modèle (CSS) utilisé par d’autres programmes (le moteur de rendu web).

    Les DSL sont très utilisés dans la conception orientée modèle, pour des supports de langages métiers a durée de vie «moyenne», i.e. une demi-douzaine d’année grand maximum.

    L’idée phare de la conception orientée modèle, c’est de différencier le modèle, le méta-modèle et le méta-méta-modèle, et de finir par coder des programmes qui codent des programmes.

    Ça reviens un peu à créer automatiquement des langages et des interfaces graphiques en assemblant des design patterns comme des lego, c’est très rigolo (sauf le moment où tu comprend que tu va faire tout ça sous eclipse, mais c’est une autre histoire).

    C’est généralement assisté par quelques frameworks, comme XText pour java, et son équivalent textx en python. Niveau académique, il y a kermeta qui est AFAIK l’état de l’art de la manipulation de méta-modèle.

  • Réchèr

    Tiens, ça ressemble à cet article : http://sametmax.com/les-mensonges-des-dsl/

    Sinon, j’ai envie de dire : “d’accord”.

    Mais dans certains cas concrets, c’est pas évident de trouver le bon formalisme.

    Par exemple, pour ce langage là : http://www.puzzlescript.net/

    C’est un DSL, comportant des défauts assez flagrants (la lettre “V” toute seule est un mot réservé du langage, par exemple).

    Mais la bonne solution ça aurait été quoi ?

    – La même chose mais en JSON ?

    – Une API Javascript, avec des événements du style “on_game_loop()”, “on_rule_match()”, … ?

    Il y a quand même quelque contraintes un peu spécifiques :

    – ça doit fonctionner dans un navigateur (mais potentiellement, ça devrait pouvoir fonctionner dans d’autres contextes comme un client lourd),

    – le langage doit rester assez simple pour qu’un non-informaticien puisse déjà commencer à faire des petits trucs,

    – re-potentiellement, on devrait pouvoir le lancer en mode pas-à-pas pour faire du debug, afficher l’état du jeu, etc.

  • Sam Post author

    Puzzle script est typiquement l’exemple même d’un endroit où une bonne API aurait été préférable. Ici le côté “création d’un autre langage” apporte zero valeur ajoutée vu que leur script est clairement complexe et en tout point inférieur à un langage battle tested.

  • Pierrot

    Super article merci, la différence entre DSL et API m’échappait jusqu’à maintenant !

    Surtout la justesse des illustrations ( +1 pour Gandhi façon Civilization ! :-D )

    Plus généralement, continuez les mecs vous êtes une grande source d’inspiration pour les dévs Python newbie comme moi ! Parfois ça vole un peu trop haut pour moi mais la plupart du temps vos articles m’ont fait gagner un temps fou en recherche diverses et variées :-)

    Au point que quand je fais une search Google pour Python je cherche vos articles en prio plutôt que ceux de stackoverflow ou la doc python officielle ! :-D

  • Andaruss

    cMake ça me fatigue d’avoir à apprendre un langage qui ne me servira qu’à ça juste pour définir le build d’un projet. Ce serait idiot de build du C++ avec du C++ mais pourquoi ne pas avoir pris n’importe quel autre langage de script bien foutu plutôt que d’inventer ce truc!

  • Ben

    Juste pour pointer que “ReactQL” n’est pas un DSL. ReactQL est un boilerplate pour application Node + React + GraphQL. Le DSL ici serait donc plutot GraphQL.

Comments are closed.

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.