DSL en Go : comment créer un langage dédié pour des tâches réelles

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

DSL en Go : transformez votre code en un nouveau langage



Imaginez que vous écrivez un système de traitement de commandes. Chaque jour, les gestionnaires demandent : « Ajoutez une remise de 10 % pour tous les clients de Moscou, mais seulement si le montant de la commande dépasse 5000 ». Vous plongez dans le code, modifiez les if-else, testez, déployez. Une semaine plus tard, nouvelle demande : « Remise de 15 % pour les VIP, si plus de trois articles ». Cela vous semble familier ?



Et si les gestionnaires pouvaient eux-mêmes écrire ces règles ? Sans votre intervention. Sans risque de casser la production. C'est exactement à cela que servent les langages dédiés (DSL) — des langages compacts, conçus pour une tâche spécifique. Et Go, avec sa simplicité et ses performances, est idéal pour créer de tels DSL.



Dans cet article, nous allons voir comment créer des DSL en Go — des solutions embarquées simples aux analyseurs externes complets. Vous apprendrez à automatiser les tâches répétitives et à offrir aux utilisateurs un outil qu'ils comprendront sans programmation.



Qu'est-ce qu'un DSL et pourquoi en a-t-on besoin en Go ?



DSL (Domain-Specific Language) est un langage de programmation créé pour un domaine restreint. Contrairement aux langages universels (Go, Python, Java), un DSL résout un seul problème, mais le fait avec élégance.



Exemples concrets :

  • SQL — DSL pour travailler avec les bases de données.
  • Regex — DSL pour rechercher des motifs dans le texte.
  • HTML — DSL pour le balisage de pages web.


En Go, les DSL sont utilisés pour :

  • Configuration — au lieu de YAML/JSON, on peut écrire la logique dans son propre langage.
  • Règles métier — permettre aux analystes de modifier la logique sans programmeurs.
  • Tests — décrire des scénarios de manière lisible.
  • Traitement de données — créer des pipelines de transformations.


Go n'a pas été choisi par hasard : son compilateur est rapide, sa syntaxe concise, et ses outils intégrés (comme text/scanner ou go/ast) simplifient l'analyse. Mais surtout, Go permet de créer à la fois des DSL internes (intégrés dans la syntaxe même de Go) et des DSL externes (avec leur propre syntaxe et analyseur).



DSL internes en Go : utiliser la syntaxe du langage



Les DSL internes sont des bibliothèques qui ressemblent à un langage distinct, mais utilisent la syntaxe de Go. Ils ne nécessitent pas d'écrire un analyseur : il suffit d'écrire des fonctions qui s'« enchaînent » en appels chaînés.



Exemple : DSL pour les règles de remises



Supposons que nous voulions que les règles ressemblent à ceci :



discount := Rule("Remise VIP").    When(City("Moscou")).    When(OrderSum > 5000).    Apply(Discount(10))


Comment implémenter cela en Go ? Utilisons le pattern Builder et les fonctions d'ordre supérieur :



package main

import "fmt"

// Rule - structure de règletype Rule struct { Name string Checks []func(order map[string]interface{}) bool Discount int}

// When ajoute une conditionfunc (r *Rule) When(check func(order map[string]interface{}) bool) *Rule { r.Checks = append(r.Checks, check) return r}

// Apply définit la remisefunc (r *Rule) Apply(discount int) *Rule { r.Discount = discount return r}

// Evaluate vérifie si la commande correspondfunc (r *Rule) Evaluate(order map[string]interface{}) bool { for _, check := range r.Checks { if !check(order) { return false } } return true}

// Fonctions de condition auxiliairesfunc City(city string) func(map[string]interface{}) bool { return func(order map[string]interface{}) bool { return order["city"] == city }}

func OrderSum(order map[string]interface{}) int { return order["sum"].(int)}

// Surcharge de l'opérateur > via une fermeturefunc GreaterThan(a func(map[string]interface{}) int, b

Blogs

Book Recommendations