Domain-Specific Languages avec le langage Groovy Guillaume Laforge VP Technology G2One, Inc.
VP Technology de G2One [email_address] Chef de projet du langage Groovy Spec Lead JSR-241 Initiateur du framework web Grails Speaker JavaOne, JavaPolis, QCon, JAX Spring Experience, TSSJS… Co-auteur du livre Groovy in Action Guillaume Laforge
Le but de cette présentation Expliquer Ce que sont les Domain-Specific Languages Où et quand utiliser un DSL Montrer Les techniques pour implémenter un DSL en Groovy Comment intégrer un DSL dans une application Java Les considérations à garder à l’esprit
DSL ? Késako ! DSL : Domain-Specific Language Un langage informatique spécifique à un  domaine particulier , qui modélise des  concepts  métier rattachés à des constructions syntaxiques de ce langage
Les caractéristiques d’un DSL C’est un langage Qui n’est pas forcément Turing complet Couvre un domaine particulier de connaissance Possède une forme : visuelle ou textuelle Produit un résultat Configure des objets, représente une structure de données… Peut  être « interne » ou « externe » Internal / embedded DSL : utilise un langage h ôte Autonome : avec son propre parseur / lexeur / compilateur Possède certains attributs de qualité Facile à écrire et à utiliser, testable, évolutif
Quelques exemples connus Technique SELECT * FROM USER WHERE NAME LIKE ‘Guil%’ ^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$  Notation 1. e4 e5 2. Nf3 Nc6 3. Bb5 a6. U R' U2 R U R' U R Métier Expression des règles de calcul de risque sur des polices d’assurance Schéma comptable d’une banque Représentation des compétences pour les ressources humaines Simulation de la résistance aux médicaments anti-malaria
Mais pourquoi créer un DSL ? Pour avoir un langage  plus expressif  et  plus lisible  qu’un langage de programmation généraliste Partager une  métaphore commune   entre tous les acteurs d’un m ême projet Permettre aux  experts métier d’aider   au développement de règles métier complexes Eviter de noyer son code métier  avec  trop de code technique  environnant Séparer plus proprement le code métier   du code applicatif technique Donner au code métier son  propre cycle de vie
Vers du code métier lisible ? Densité  sémantique métier 20%
Vers du code métier lisible ? 80%
Groovy à la rescousse Les techniques pour implémenter des DSLs en utilisant le langage dynamique Groovy pour la machine virtuelle Java
Mais déjà, qu’est-ce que Groovy ? Groovy est un  langage dynamique  alternatif pour la JVM Compilé en bytecode Java ou interprété Projet  Open Source  (licence Apache) Hébergé par la communauté Codehaus Syntaxe  dérivée de Java , mais plus souple Reprend des idées de Smalltalk, Ruby et Python Syntaxe native Listes, dictionnaires, intervalles, expression régulières Supporte le  typage optionnel Typage dynamique ou typage statique au choix Fonctionnalités avancées Closures , properties,  surcharge d’opérateurs …
La différence avec Java ? Java est un langage statiquement compilé Le comportement total du code est gravé dans le marbre (dans le bytecode que la JVM exécute) Les langages dynamiques comme Groovy Peuvent  modifier le comportement du code à l’exécution au travers du « MetaObject Protocol » (on peut m ême écrire 1+1==1 !) Interception d’appel de méthode, de propriété (m ême inexistante !) Surcharge d’opérateur, création de structures de contrôle, etc.
Rajouter des propriétés à des nombres Tout est objet  en Groovy, m ême les nombres Par interception de l’accès aux propriétés Number.metaClass.getEuros = { new CurrencyAmount(delegate, Currency.EUROS) } Exemples 30.euros 4.pills 50.kilo.meters
Surcharge d’opérateurs Surcharge par implémentation de méthodes + a.plus(b) - a.minus(b) * a.multiply(b) / a.divide(b) % a.modulo(b) | a.or(b) & a.and(b) a[b] a.getAt(b) a << b a.leftShift(b) Monnaies 30.euros + 15.euros Distances 12.kilo.meters + 300.meters Workflow, concurrence taskA | taskB & taskC Créditer un compte account << 10.euros Account += 10.euros
BigDecimal et surcharge Par défaut, les nombres à virgule sont des BigDecimal Idéal pour le calcul exact (pas d’erreur d’arrondi) Important dans la banque / finance / assurance Mutual of Omaha, assurance américaine (Fortune 500) Utilise Groovy pour son moteur de calcul de risque Expressivité des règles de calcul BigDecimal uMinusv = c.subtract(a);  BigDecimal vMinusl = b.subtract(c);  BigDecimal uMinusl = a.subtract(b);  return e.multiply(uMinusv) .add(d.multiply(vMinusl)) .divide(uMinusl, 10, BigDecimal.ROUND_HALF_UP); (d * (b - c) + e * (c - a)) / (a - b)
Syntaxe malléable Parenthèses et point-virgule optionnels move left Paramètres nommés monster.move x: 3.meters, y: 4.meters compare indicator: ‘NIKEI’, withFund: ‘Aberdeen’ Syntaxe native Liste : [Monday, Wednesday, Friday] Dictionnaire : [buy: 300.GOOG, sell: 1000.MSFT] Intervalles : Monday..Friday
Le concept de « builder » Support du pattern « builder » au niveau syntaxique Gr âce à des appels de méthodes chaînées et de passage de c losures en paramètre etre {   idees {   capture 2   formule 3   produit 4   } } faire {   build {   J2EE 4   } }
Structures de contr ôle customisées Raccourci de notation pour un appel de méthode avec une closure comme dernier paramètre unless(account.balance < 0, { account.debit 10.euros }) unless(account.balance< 0) {    account.debit 10.euros  } Quelques idées withLock(lock) { … } transactional { … } execute (in: 3.hours) {  }
Intégrer un DSL Groovy  dans une application Java JSR-223: javax.script.* Mécanismes spécifiques Groovy Spring 2 dynamic beans
JSR-223 : javax.script.* Dans JDK 6, nouvelle API basique  pour manipuler et intégrer les langages de script Scripting.dev.java.net propose un moteur pour Groovy à mettre dans son classpath avec les JARs Groovy ScriptEngineManager mgr = new ScriptEngineManager(); ScriptEngine engine = mgr.getEngineByName(‘groovy’); String result = (String)engine.eval(« ’foo’ * 2 »);
Mécanismes Groovy Groovy propose plusieurs mécanismes Eval  : pour évaluer des expressions simples GroovyShell  : pour intéragir avec des scripts et expressions complexes GroovyScriptEngine  : lorsqu’il y a des dépendances entre scripts GroovyClassLoader  : mécanisme le plus puissant à la base de tous les autres Bien que propriétaires, ce sont les mécanismes  les plus puissants pour écrire et intégrer des DSLs  dans une application Java
Beans dynamiques dans Spring 2 Des beans peuvent  être configurés avec des langages alternatifs tels que Groovy Un POGO peut-être configuré / proxifié / injecté Interopérabilité avec POJO transparente On peut  mixer Java et Groovy ensemble Nouveau namespace <lang:groovy/> Possibilité de  rechargement à chaud sur modification Personnalisation du comportement au runtime <lang:groovy id=&quot;events&quot;    script-source=&quot;classpath:dsl/eventsChart.groovy&quot;    customizer-ref=&quot;eventsMetaClass&quot; />
Considérations à garder à l’esprit S’assurer de l’adoption du DSL Suivre un processus itératif Techniques défensives de programmation
S’assurer de l’adoption d’un DSL Ne pas forcer l’adoption ! Faire en sorte que les utilisateurs finaux construisent leur propre langage  (avec notre aide) Ne pas le créer seul devant son écran Impliquer les utilisateurs régulièrement   à chaque évolution ou nouveau concept métier à représenter Etudier comment ils emploient ce DSL, pour l’améliorer Guider les utilisateurs  pour leur indiquer  ce qu’il est possible de faire avec Groovy
Suivre un processus itératif Commencer simple, avec les concepts primordiaux Se rappeler qu’on n’a jamais tout bon la première fois Retourner brainstormer avec les experts métier pour une amélioration continue du DSL Tester continuellement
Programmation défensive Exécuter un DSL de type « embedded » peut -être dangereux ! System.exit(0); Un DSL doit tourner dans un « bac à sable » Tester, tester, tester ! Echouer avec gr âce en donnant  toujours des messages d’erreurs lisibles Ne pas tester que les cas valides,  tester explicitement les erreurs
Conclusion : Vers plus d’expressivité
Conclusion Les DSLs sont un excellent moyen  pour partager une métaphore commune  entre développeurs et experts métier Ils permettent de se  focaliser sur le métier , en masquant une grande partie du code technique Externalisation possible, cycle de vie distinct Groovy est idéal  de par sa nature et sa syntaxe malléable pour d’écrire des DSLs de type « embedded » Toujours garder les considérations en t ête pour s’assurer de l’adoption et la bonne évolution de son DSL
Questions / Réponses [email_address]

Domain-Specific Languages avec Groovy

  • 1.
    Domain-Specific Languages avecle langage Groovy Guillaume Laforge VP Technology G2One, Inc.
  • 2.
    VP Technology deG2One [email_address] Chef de projet du langage Groovy Spec Lead JSR-241 Initiateur du framework web Grails Speaker JavaOne, JavaPolis, QCon, JAX Spring Experience, TSSJS… Co-auteur du livre Groovy in Action Guillaume Laforge
  • 3.
    Le but decette présentation Expliquer Ce que sont les Domain-Specific Languages Où et quand utiliser un DSL Montrer Les techniques pour implémenter un DSL en Groovy Comment intégrer un DSL dans une application Java Les considérations à garder à l’esprit
  • 4.
    DSL ? Késako! DSL : Domain-Specific Language Un langage informatique spécifique à un domaine particulier , qui modélise des concepts métier rattachés à des constructions syntaxiques de ce langage
  • 5.
    Les caractéristiques d’unDSL C’est un langage Qui n’est pas forcément Turing complet Couvre un domaine particulier de connaissance Possède une forme : visuelle ou textuelle Produit un résultat Configure des objets, représente une structure de données… Peut être « interne » ou « externe » Internal / embedded DSL : utilise un langage h ôte Autonome : avec son propre parseur / lexeur / compilateur Possède certains attributs de qualité Facile à écrire et à utiliser, testable, évolutif
  • 6.
    Quelques exemples connusTechnique SELECT * FROM USER WHERE NAME LIKE ‘Guil%’ ^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$ Notation 1. e4 e5 2. Nf3 Nc6 3. Bb5 a6. U R' U2 R U R' U R Métier Expression des règles de calcul de risque sur des polices d’assurance Schéma comptable d’une banque Représentation des compétences pour les ressources humaines Simulation de la résistance aux médicaments anti-malaria
  • 7.
    Mais pourquoi créerun DSL ? Pour avoir un langage plus expressif et plus lisible qu’un langage de programmation généraliste Partager une métaphore commune entre tous les acteurs d’un m ême projet Permettre aux experts métier d’aider au développement de règles métier complexes Eviter de noyer son code métier avec trop de code technique environnant Séparer plus proprement le code métier du code applicatif technique Donner au code métier son propre cycle de vie
  • 8.
    Vers du codemétier lisible ? Densité sémantique métier 20%
  • 9.
    Vers du codemétier lisible ? 80%
  • 10.
    Groovy à larescousse Les techniques pour implémenter des DSLs en utilisant le langage dynamique Groovy pour la machine virtuelle Java
  • 11.
    Mais déjà, qu’est-ceque Groovy ? Groovy est un langage dynamique alternatif pour la JVM Compilé en bytecode Java ou interprété Projet Open Source (licence Apache) Hébergé par la communauté Codehaus Syntaxe dérivée de Java , mais plus souple Reprend des idées de Smalltalk, Ruby et Python Syntaxe native Listes, dictionnaires, intervalles, expression régulières Supporte le typage optionnel Typage dynamique ou typage statique au choix Fonctionnalités avancées Closures , properties, surcharge d’opérateurs …
  • 12.
    La différence avecJava ? Java est un langage statiquement compilé Le comportement total du code est gravé dans le marbre (dans le bytecode que la JVM exécute) Les langages dynamiques comme Groovy Peuvent modifier le comportement du code à l’exécution au travers du « MetaObject Protocol » (on peut m ême écrire 1+1==1 !) Interception d’appel de méthode, de propriété (m ême inexistante !) Surcharge d’opérateur, création de structures de contrôle, etc.
  • 13.
    Rajouter des propriétésà des nombres Tout est objet en Groovy, m ême les nombres Par interception de l’accès aux propriétés Number.metaClass.getEuros = { new CurrencyAmount(delegate, Currency.EUROS) } Exemples 30.euros 4.pills 50.kilo.meters
  • 14.
    Surcharge d’opérateurs Surchargepar implémentation de méthodes + a.plus(b) - a.minus(b) * a.multiply(b) / a.divide(b) % a.modulo(b) | a.or(b) & a.and(b) a[b] a.getAt(b) a << b a.leftShift(b) Monnaies 30.euros + 15.euros Distances 12.kilo.meters + 300.meters Workflow, concurrence taskA | taskB & taskC Créditer un compte account << 10.euros Account += 10.euros
  • 15.
    BigDecimal et surchargePar défaut, les nombres à virgule sont des BigDecimal Idéal pour le calcul exact (pas d’erreur d’arrondi) Important dans la banque / finance / assurance Mutual of Omaha, assurance américaine (Fortune 500) Utilise Groovy pour son moteur de calcul de risque Expressivité des règles de calcul BigDecimal uMinusv = c.subtract(a); BigDecimal vMinusl = b.subtract(c); BigDecimal uMinusl = a.subtract(b); return e.multiply(uMinusv) .add(d.multiply(vMinusl)) .divide(uMinusl, 10, BigDecimal.ROUND_HALF_UP); (d * (b - c) + e * (c - a)) / (a - b)
  • 16.
    Syntaxe malléable Parenthèseset point-virgule optionnels move left Paramètres nommés monster.move x: 3.meters, y: 4.meters compare indicator: ‘NIKEI’, withFund: ‘Aberdeen’ Syntaxe native Liste : [Monday, Wednesday, Friday] Dictionnaire : [buy: 300.GOOG, sell: 1000.MSFT] Intervalles : Monday..Friday
  • 17.
    Le concept de« builder » Support du pattern « builder » au niveau syntaxique Gr âce à des appels de méthodes chaînées et de passage de c losures en paramètre etre { idees { capture 2 formule 3 produit 4 } } faire { build { J2EE 4 } }
  • 18.
    Structures de contrôle customisées Raccourci de notation pour un appel de méthode avec une closure comme dernier paramètre unless(account.balance < 0, { account.debit 10.euros }) unless(account.balance< 0) { account.debit 10.euros } Quelques idées withLock(lock) { … } transactional { … } execute (in: 3.hours) { }
  • 19.
    Intégrer un DSLGroovy dans une application Java JSR-223: javax.script.* Mécanismes spécifiques Groovy Spring 2 dynamic beans
  • 20.
    JSR-223 : javax.script.*Dans JDK 6, nouvelle API basique pour manipuler et intégrer les langages de script Scripting.dev.java.net propose un moteur pour Groovy à mettre dans son classpath avec les JARs Groovy ScriptEngineManager mgr = new ScriptEngineManager(); ScriptEngine engine = mgr.getEngineByName(‘groovy’); String result = (String)engine.eval(« ’foo’ * 2 »);
  • 21.
    Mécanismes Groovy Groovypropose plusieurs mécanismes Eval : pour évaluer des expressions simples GroovyShell : pour intéragir avec des scripts et expressions complexes GroovyScriptEngine : lorsqu’il y a des dépendances entre scripts GroovyClassLoader : mécanisme le plus puissant à la base de tous les autres Bien que propriétaires, ce sont les mécanismes les plus puissants pour écrire et intégrer des DSLs dans une application Java
  • 22.
    Beans dynamiques dansSpring 2 Des beans peuvent être configurés avec des langages alternatifs tels que Groovy Un POGO peut-être configuré / proxifié / injecté Interopérabilité avec POJO transparente On peut mixer Java et Groovy ensemble Nouveau namespace <lang:groovy/> Possibilité de rechargement à chaud sur modification Personnalisation du comportement au runtime <lang:groovy id=&quot;events&quot; script-source=&quot;classpath:dsl/eventsChart.groovy&quot; customizer-ref=&quot;eventsMetaClass&quot; />
  • 23.
    Considérations à garderà l’esprit S’assurer de l’adoption du DSL Suivre un processus itératif Techniques défensives de programmation
  • 24.
    S’assurer de l’adoptiond’un DSL Ne pas forcer l’adoption ! Faire en sorte que les utilisateurs finaux construisent leur propre langage (avec notre aide) Ne pas le créer seul devant son écran Impliquer les utilisateurs régulièrement à chaque évolution ou nouveau concept métier à représenter Etudier comment ils emploient ce DSL, pour l’améliorer Guider les utilisateurs pour leur indiquer ce qu’il est possible de faire avec Groovy
  • 25.
    Suivre un processusitératif Commencer simple, avec les concepts primordiaux Se rappeler qu’on n’a jamais tout bon la première fois Retourner brainstormer avec les experts métier pour une amélioration continue du DSL Tester continuellement
  • 26.
    Programmation défensive Exécuterun DSL de type « embedded » peut -être dangereux ! System.exit(0); Un DSL doit tourner dans un « bac à sable » Tester, tester, tester ! Echouer avec gr âce en donnant toujours des messages d’erreurs lisibles Ne pas tester que les cas valides, tester explicitement les erreurs
  • 27.
    Conclusion : Versplus d’expressivité
  • 28.
    Conclusion Les DSLssont un excellent moyen pour partager une métaphore commune entre développeurs et experts métier Ils permettent de se focaliser sur le métier , en masquant une grande partie du code technique Externalisation possible, cycle de vie distinct Groovy est idéal de par sa nature et sa syntaxe malléable pour d’écrire des DSLs de type « embedded » Toujours garder les considérations en t ête pour s’assurer de l’adoption et la bonne évolution de son DSL
  • 29.
    Questions / Réponses[email_address]