Journal Sortie de Groovy 4.0.0

Posté par  (site web personnel) . Licence CC By‑SA.
Étiquettes :
12
31
jan.
2022

Sommaire

Groovy est un langage typé optionnellement, dynamique, pouvant supporter la compilation statique. Il utilise la plateforme Java, il permet entre autres la composition de scripts portables (Windows, Linux, Mac avec gestion de dépendances), tout en disposant d’une syntaxe simple et abordable.

Groovy simplifie également la création de DSL, la méta-programmation, la programmation fonctionnelle et la rédaction de tests.

Amélioration de l’existant

Utilisation exclusive du Parrot parser

Il s'agit d'une version optimisée d'ANTLR4 en lieu et place de l’ancien parseur basé sur Antlr2, ce qui permet plus de flexibilité et rend la syntaxe compatible avec celle de Java (c.f. Parrot Parser).

Compatibilité à partir du Jdk 7+

L’un des avantages de Groovy étant le support d’ ancienne version du Jdk.

Nouvelles fonctionnalités (non-incubating)

Voir New Features

Switch expressions

Similaire à ce que propose Java, sauf que la branche default n’est pas obligatoire, dans ce cas null est retourné.

def result = switch(i) {
    case 0 -> 'zero'
    case 1 -> 'one'
    case 2 -> 'two'
    default -> throw new IllegalStateException('unknown number')
}

On peut toujours utiliser les anciennes expressions

def items = [10, -1, 5, null, 41, 3.5f, 38, 99, new Coord(x: 4, y: 5), 'foo']
def result = items.collect { a ->
  switch(a) {
    case null -> 'null'
    case 5 -> 'five'
    case new Custom() -> 'custom'
    case 0..15 -> 'range'
    case [37, 41, 43] -> 'prime'
    case Float -> 'float'
    case { it instanceof Number && it % 2 == 0 } -> 'even'
    case Coord -> a.with { "x: $x, y: $y" }
    case ~/../ -> 'two chars'
    default -> 'none of the above'
  }
}

Pratique pour le pattern "visitor" :

import groovy.transform.Immutable

interface Expr { }
@Immutable class IntExpr implements Expr { int i }
@Immutable class NegExpr implements Expr { Expr n }
@Immutable class AddExpr implements Expr { Expr left, right }
@Immutable class MulExpr implements Expr { Expr left, right }

int eval(Expr e) {
    e.with {
        switch(it) {
            case IntExpr -> i
            case NegExpr -> -eval(n)
            case AddExpr -> eval(left) + eval(right)
            case MulExpr -> eval(left) * eval(right)
            default -> throw new IllegalStateException()
        }
    }
}

@Newify(pattern=".*Expr")
def test() {
    def exprs = [
        IntExpr(4),
        NegExpr(IntExpr(4)),
        AddExpr(IntExpr(4), MulExpr(IntExpr(3), IntExpr(2))), // 4 + (3*2)
        MulExpr(IntExpr(4), AddExpr(IntExpr(3), IntExpr(2)))  // 4 * (3+2)
    ]
    assert exprs.collect { eval(it) } == [4, -4, 10, 20]
}

test()

Sealed Class

La GEP correspondante.

Record-like classes

La définition dans la langue de Shakespeare

model plain data aggregates with less ceremony

record Cyclist(String firstName, String lastName) { }
def richie = new Cyclist('Richie', 'Porte')

Built-in type checkers

Test de la validité des données pendant la phase de compilation, pour le moment limité aux expressions régulières :

@TypeChecked(extensions = 'groovy.typecheckers.RegexChecker')
def whenIs2020Over() {
    def newYearsEve = '2020-12-31'
    def matcher = newYearsEve =~ /(\d{4})-(\d{1,2})-(\d{1,2}/
}

Conduit à une erreur à la compilation :

1 compilation error:
[Static type checking] - Bad regex: Unclosed group near index 26
(\d{4})-(\d{1,2})-(\d{1,2}
 at line: 6, column: 19

Built-in macro methods

println NV(num, list, range, string)

Affiche num=42, list=[1, 2, 3], range=[0, 1, 2, 3, 4, 5], string=foo. Le nom de la variable s'affiche avec son contenu.

println NVI(range)

Affiche range=0..5, c'est l'expression qui définit le range qui est affichée.

NVD est une macro qui affiche le dump().

Autres améliorations

Amélioration des performances liées à la gestion des GString

  • Mise en cache du résultat de toString() lorsque cela s'avère sûr ;
  • Ajout de la méthode freeze() pour forcer cette mise en cache.

Enhanced Ranges

Actuellement les "ranges" n'étaient que inclusifs (3..5) ou ouverts à droite (4..<10), depuis Groovy 4, les "ranges" peuvent être clos à gauche ou à droite.

Décimal sans zéro en en-tête

Maintenant le code suivant est valide :

def half = .5
def otherHalf = 0.5  // leading zero remains supported
double third = .333d
float quarter = .25f
def fractions = [.1, .2, .3]

Pour les ranges, à droite, il faudra cependant conserver le zéro.

Autres nouveautés en "incubation"

Groovy Contracts

Ajout d'annotation pour la programmation par contrats :

import groovy.contracts.*

@Invariant({ speed() >= 0 })
class Rocket {
    int speed = 0
    boolean started = true

    @Requires({ isStarted() })
    @Ensures({ old.speed < speed })
    def accelerate(inc) { speed += inc }

    def isStarted() { started }

    def speed() { speed }
}

def r = new Rocket()
r.accelerate(5)

Groovy-Integrated Query

Requête de type SQL sur les objets en mémoire (lists, maps, JSON ou XML) :

assert GQ {
    from p in json.prices
    join c in json.vitC on c.name == p.name
    orderby c.conc / p.price in desc
    limit 2
    select p.name
}.toList() == ['Kakuda plum', 'Kiwifruit']

Voila, le nouveau parseur permettra de plus aisément étendre les fonctionnalités de ce langage, qui profite de l'infrastructure du monde Java pour rendre celui-ci plus accessible.

  • # C'était proprio ?

    Posté par  (site web personnel) . Évalué à 10.

    La manie de vouloir absolument traduire les termes anglais que tout le monde comprend… moi je la comprend pas.

    Release of Groovy 4.0

    Ça se traduirait par :

    Sortie de Groovy 4.0

    Bien que Google Translate traduit "to release" en "libérer" (dans le sens libérer de prison). C'est pas le cas ici. Pour le coup "libération de [SOFTWARE]" ça signifie qu'il était propriétaire et qu'il est sorti sous licence libre. On est bien loin de la réalité ici.

    Sur une note plus positive, ravi que le langage derrière les Jenkinsfile continue d'évoluer. Merci pour cette mise en bouche.

    https://link-society.com - https://kubirds.com

    • [^] # Re: C'était proprio ?

      Posté par  (site web personnel) . Évalué à 3.

      Corrigé, merci.

    • [^] # Re: C'était proprio ?

      Posté par  . Évalué à 1. Dernière modification le 31 janvier 2022 à 17:10.

      Le débat a surement déjà eu lieu, mais bon… En plus d'être d'accord avec le commentaire auquel je réponds, j'ajouterai que les francisations qui n'existent (quasiment) pas dans le language courant sont vraiment reloues …

      Quand vous discutez, vous dites "t'as vu la dernière release de X ?" ou bien "t'as sur la dernière sortie/libération de X ?" ?… J'aimerai bien connaitre la proportion des gens qui utilisent un mot français dans cet exemple.

      Je suis pour la francisation des termes, mais ça doit aussi refléter la réalité … courriel, par exemple, que je ne trouve pas si mal, n'a jamais su s'imposer dans le langage courant, pourtant ça fait des années qu'il existe … Je ne connais aucun professionnel de l'informatique que dit "courriel", et même Mme Michu dit "email", pas "courriel" (j'ai pris cet exemple car email est justement aussi très utilisé par les non-informaticiens).

      • [^] # Re: C'était proprio ?

        Posté par  (site web personnel) . Évalué à -1. Dernière modification le 31 janvier 2022 à 17:16.

        j'ajouterai que les francisations qui n'existent (quasiment) pas dans le language courant sont vraiment reloues …

        Exemple, toutes les déviations de "logiciel" :

        • cadriciel, systématiquement je dois googler pour me rendre compte qu'on parle de "framework"
        • progiciel pour logiciel propriétaire
        • maliciel, pour malware
        • gratuiciel, pour freeware
        • cacaciel, pour la blague

        Après, il y a les faux amis qui sont mal traduit :

        • library -> c'est bibliothèque, pas librairie, merci

        Je suis pour la francisation des termes, mais ça doit aussi refléter la réalité …

        La réalité c'est que 99% de la littérature informatique et technique est en anglais. Et que la nomenclature qui en dérive, est anglaise. Pour un débutant dans le domaine, c'est difficile de devoir apprendre des termes que de toute façon personne n'utilise.

        Je dis plus souvent kernel que noyau, je dis booter et pas démarrer, je continuerai de dire framework, library, software et bullshit au lieu de cadriciel, bibliothèque, logiciel et merde de taureau.

        https://link-society.com - https://kubirds.com

      • [^] # Re: C'était proprio ?

        Posté par  (site web personnel, Mastodon) . Évalué à 10.

        Oh, un sondage…
        Je me considère comme un professionnel de l'informatique mais je ne dois pas l'être vu que j'utilise les termes français… et que je trouve que ça facilite la compréhension…

        “It is seldom that liberty of any kind is lost all at once.” ― David Hume

      • [^] # Re: C'était proprio ?

        Posté par  . Évalué à 10.

        "t'as vu la dernière release de X ?"
        donne
        "t'as vu la dernière version de X ?"

        c'est très utilisé

        • [^] # Re: C'était proprio ?

          Posté par  (site web personnel) . Évalué à 10.

          Google
          "t'as vu la dernière release de" 1 résultat (0,31 secondes)
          "t'as vu la dernière version de" Environ 7 résultats (0,36 secondes)

          Bing
          "t'as vu la derniere release de" 75 300 résultats
          "t'as vu la dernière release de" 1 résultats (sic)
          "t'as vu la derniere version de" 161 000 résultats
          "t'as vu la dernière version de" 2 résultats

          Bon ben c'est clair grâce à cette approche data-scientiste de ouf : « Selon une étude américaine », version est entre deux et sept plus utilisé que release.

        • [^] # Re: C'était proprio ?

          Posté par  (site web personnel) . Évalué à 2.

          Une release et une version, c'est pas pareil. Y'a potentiellement plusieurs versions entre deux releases, mais pas l'inverse.

          • [^] # Re: C'était proprio ?

            Posté par  (site web personnel) . Évalué à 2.

            ya une différence entre version interne et version publiée :-) (ce pourquoi il y communication)

            moui, si tu fournis

            • la version svn : bah c'est incrémental, des entiers généralement
            • la version git : qui lit le hash dans le texte (non, pas toi au fonds de la classe) ? Mais oui pour qui suit les dévs, c'est évident (vu que c'est tagué release)

            ça m'a bien pourri la vie cette gestion de la comm' sur les versions :-)
            Une alternative est de leur donner un nom comme traktopel, mais ce n'est pas satisfaisant : comment tu gères les mises à jour ? (.1, .2 mouais on va dire)

            Si seulement ça nous donnait des contributeurs de plus :/

      • [^] # Re: C'était proprio ?

        Posté par  (site web personnel) . Évalué à 5.

        Le débat a surement déjà eu lieu, mais bon… En plus d'être d'accord avec le commentaire auquel je réponds, j'ajouterai que les francisations qui n'existent (quasiment) pas dans le language courant sont vraiment reloues …

        Ca depend du pays. Y'a plein de traductions courantes au Quebec qui sont rares en France. Ca ne me derange pasWplus de les utiliser.

    • [^] # Re: C'était proprio ?

      Posté par  (site web personnel) . Évalué à 6. Dernière modification le 31 janvier 2022 à 17:20.

      C'était volontaire et non issu de Google Trad. C'est comme bronsonizer, je pensais que c'était un running gag…

      Sortie, peut avoir une connotation négative et déjà vu. Je préfère publication. Mais bon.

    • [^] # Re: C'était proprio ?

      Posté par  (site web personnel) . Évalué à 8. Dernière modification le 31 janvier 2022 à 18:08.

      La manie de vouloir absolument traduire les termes anglais que tout le monde comprend… moi je la comprend pas.

      Que tout le monde comprend, c'est pas évident, faudrait faire un sondage.

      Au delà de ça, en fonction du contexte, tout le monde a probablement une limite d'acceptabilité de l'artificialisation du langage, dont la jargonnalisation procède. Par exemple je trouve disgratieux et potentiellement pas clair l'idée d'uploader sa ssh-key pour checkouter son repo.

      Adhérer à l'April, ça vous tente ?

      • [^] # Re: C'était proprio ?

        Posté par  (Mastodon) . Évalué à 5.

        Tu préfères téléverser ta clé ssh pour extraire ton dépôt ?

        • [^] # Re: C'était proprio ?

          Posté par  (site web personnel) . Évalué à 5.

          perso, je mets en ligne ma clé ssh pour récupérer le dépôt… parce que bon (pour moi) :

          • téléverser niet, uploader moui mais non, télécharger ah bin non
          • checkouter niet, extraire moui éventuellement

          les traductions mot-à-mot sont souvent casse-gueule, l'adaptation à chaque langue peut demander des périphrases (n'empêchant pas de rappeler la commande à laquelle on fait effectivement référence entre parenthèses)

          • [^] # Re: C'était proprio ?

            Posté par  (site web personnel, Mastodon) . Évalué à 5.

            Et en l'occurrence c'est bien « récupérer le dépôt » et non l'extraire… C'est pour ça que je disais dans un autre commentaire que ne pas jargonner inutilement permet de s'assurer de ce dont on parle ; pas faire comme avec la novlangue du marketing et de la politique…

            “It is seldom that liberty of any kind is lost all at once.” ― David Hume

            • [^] # Re: C'était proprio ?

              Posté par  (site web personnel) . Évalué à 5.

              ne pas jargonner inutilement permet de s'assurer de ce dont on parle

              oui, c'est bien mon propos

              pas faire comme avec la novlangue du marketing et de la politique…

              je ne vois pas le rapport ; perso, je me contente de parler français et ça me suffit :-)
              que cela soit approprié par d'autres est de leur responsabilité (et, oui, je fais la distinction)

          • [^] # Re: C'était proprio ?

            Posté par  (site web personnel) . Évalué à 7. Dernière modification le 01 février 2022 à 12:06.

            télécharger ah bin non

            Pourquoi pas ? Ce n’est pas parce que l’anglais a deux mots distincts pour “download” et “upload” que le français devrait forcément faire de même.

            Il n’y a aucune raison pour chercher absolument à avoir une correspondance 1–1 entre les deux langues. On peut déjà trouver plein d’exemples où un mot dans une langue peut correspondre à plusieurs mots dans une autre.

            Par exemple, le mot français « quai » se traduira en anglais par “platform” ou “dock”, selon que l’on parle d’un quai ferroviaire ou d’un quai portuaire. À l’inverse, on traduira les mots français « fenêtre » et « hublot » par le même mot anglais « window », parce que l’anglais ne fait pas de distinction entre une fenêtre dans le mur d’une maison et un hublot dans la paroi d‘un avion ou d’un bateau.

            Je ne vois donc aucun problème à considérer que « télécharger » veut dire au sens large « transférer entre deux machines », sans distinction sur le sens du transfert (de machine distante à machine locale, ou l’inverse).

            Soit le contexte est suffisant pour faire la différence (par exemple, si je dis « je télécharge la dernière version du noyau Linux », il y a des chances pour que ce soit du download, sauf peut-être si je suis Linus Torvalds), soit il suffit de rendre le sens du transfert explicite (« je télécharge ma clef SSH vers le serveur », « je télécharge l’archive depuis le dépôt public »).

            Personnellement ça me semble largement plus élégant que « téléverser » ou assimilés, and that’s the hill I am willing to die on.

      • [^] # Re: C'était proprio ?

        Posté par  (site web personnel) . Évalué à -3.

        Que tout le monde comprend, c'est pas évident, faudrait faire un sondage.

        Comme je l'ai dit dans un autre commentaire. La majeure partie de la littérature informatique et technique est en anglais.

        Il est donc très très peu probable qu'un individu ne rencontre jamais les termes anglais. Il est de même très probable que ce même individu ne rencontre jamais les termes français. D'ailleurs pour être honnête, la plupart de ces termes, je ne les vois QUE sur LinuxFR.

        Au delà de ça, en fonction du contexte, tout le monde a probablement une limite d'acceptabilité de l'artificialisation du langage, dont la jargonnalisation procède.

        Kamoulox!

        Par exemple je trouve disgratieux et potentiellement pas clair l'idée d'uploader sa ssh-key pour checkouter son repo.

        Merci de prendre cet exemple.

        • "to download" -> télécharger
        • "to upload" -> télécharger

        Et non ! Téléverser est un néologisme, il n'existe pas dans le dictionnaire de l'académie française.

        Du coup, la vraie traduction de "upload an ssh-key to checkout a repository", c'est "télécharger une clé SSH pour récupérer un dépôt".

        On est d'accord que c'est sujet à confusion ?

        https://link-society.com - https://kubirds.com

        • [^] # Re: C'était proprio ?

          Posté par  (site web personnel) . Évalué à 7.

          Et non ! Téléverser est un néologisme, il n'existe pas dans le dictionnaire de l'académie française.

          Être un néologisme ne l’empêchera pas d’entrer dans un dictionnaire (celui-là ou un autre) si on l’utilise. Les dictionnaires sont d’abord le reflet de l’usage vivant, que la langue reflète un dictionnaire est un processus second.

          Note : « Télécharger » n’existe pas non-plus dans le dictionnaire de l’académie française…

          Par contre « Télégraphier » est présent, il y a donc un espoir pour Télécharger et Téléverser.

          ce commentaire est sous licence cc by 4 et précédentes

        • [^] # Re: C'était proprio ?

          Posté par  (site web personnel) . Évalué à 10. Dernière modification le 31 janvier 2022 à 20:28.

          Et non ! Téléverser est un néologisme, il n'existe pas dans le dictionnaire de l'académie française.

          L'Académie française n'est pas l'alpha et l'oméga de la langue française, ni en France ni dans la Francophonie d'ailleurs :). D'autant que la 9e édition de leur dictionnaire s'arrête à Sérénissime, ce qui réduit pas mal les chances d'y voir téléverser ou télécharger (cf
          https://www.academie-francaise.fr/le-dictionnaire/la-9e-edition « De Savoir-faire à Sérénissime : DA n°1 du 19 février 2020. », et « Vous pouvez consulter la neuvième édition du Dictionnaire de l’Académie française (de A à Sabéisme) en ligne »).

          Office québécois de la langue française, 2015
          https://gdt.oqlf.gouv.qc.ca/ficheOqlf.aspx?Id_Fiche=2075523

          "téléverser site:gouv.fr" sur les sites gouvernementaux français

          téléchargement uniquement pour la commission de terminologie du Ministère français de la culture
          http://www.culture.fr/franceterme/terme/INFO77

          La loi française, dont le Code de la propriété intellectuelle L 137.1
          https://www.legifrance.gouv.fr/search/all?tab_selection=all&searchField=ALL&query=t%C3%A9l%C3%A9verser&page=1&init=true

        • [^] # Re: C'était proprio ?

          Posté par  (site web personnel) . Évalué à 8. Dernière modification le 01 février 2022 à 10:41.

          D'ailleurs pour être honnête, la plupart de ces termes, je ne les vois QUE sur LinuxFR.

          Alors c'est que tu manque de lectures. :)

          Personnellement je pense qu'un modèle de précision sans jargon est le blog de Stéphane Bortzmeyer (bortzmeyer.org). Il y en a probablement d'autres mais je trouve celui-ci très affûté sur la question.

          Je pense personnellement que ça rend le contenu plus clair. D'une part car, bien que côtoyant l'anglais scolaire et technique depuis très longtemps, la plupart des idiomes et autres éléments culturels me sont inconnus. D'autre part car il me semble ça aide mettre le discours à l'épreuve (trituration, réification).

          Adhérer à l'April, ça vous tente ?

  • # Compatibilité à partir du Jdk 7+

    Posté par  . Évalué à 3.

    Compatibilité à partir du Jdk 7+

    L’un des avantages de Groovy étant le support d’ ancienne version du Jdk.

    Et que toutes les fonctionnalités présentées sont disponibles sur toutes les versions du jdk.

    Les records par exemples reposent directement sur le JDK quand c'est disponible (à partir de la version 17 (ou 16 ?)) et sont implémentées par groovy dans les versions précédentes du jdk.

    Groovy-Integrated Query

    J'ai eu beaucoup de mal à comprendre. Prendre l'exemple le plus sophistiqué de la release note en oublié la moitié de l'exemple n'aide pas.

    import groovy.json.JsonSlurper
    def json = new JsonSlurper().parseText('''
    {
        "prices": [
            {"name": "Kakuda plum",      "price": 13},
            {"name": "Camu camu",        "price": 25},
            {"name": "Acerola cherries", "price": 39},
            {"name": "Guava",            "price": 2.5},
            {"name": "Kiwifruit",        "price": 0.4},
            {"name": "Orange",           "price": 0.4}
        ],
        "vitC": [
            {"name": "Kakuda plum",      "conc": 5300},
            {"name": "Camu camu",        "conc": 2800},
            {"name": "Acerola cherries", "conc": 1677},
            {"name": "Guava",            "conc": 228},
            {"name": "Kiwifruit",        "conc": 144},
            {"name": "Orange",           "conc": 53}
        ]
    }
    ''')
    assert GQ {
        from p in json.prices
        join c in json.vitC on c.name == p.name
        orderby c.conc / p.price in desc
        limit 2
        select p.name
    }.toList() == ['Kakuda plum', 'Kiwifruit']

    Sachant que ce n'est pas lié à json.

    https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

    • [^] # Re: Compatibilité à partir du Jdk 7+

      Posté par  (site web personnel) . Évalué à 2.

      Mea maxima culpa, cette fonctionnalité mérite que l'on s'y attarde, j'avais peu de temps, aussi mettre du JSON dans des exemples de code pour illustrer un langage me révulse.

      Voici un autre exemple avec des objets classiques :

      enum Location {
       US('USA'), EU('Europe')
      
       Location(String label) {
           this.label = label
       }
      
       final String label
      }
      
      final class Machine {
          Location loc
          String name
          List<String> profile
      }
      
      def m1 = new Machine(loc: Location.EU, name: 'Tartanpion', profile: ['web', 'bi'])
      def m2 = new Machine(loc: Location.US, name: 'Escalope', profile: ['web', 'backend'])
      def m3 = new Machine(loc: Location.EU, name: 'Jambon', profile: ['bi'])
      def m4 = new Machine(loc: Location.US, name: 'Tartuffe', profile: ['web'])
      def m5 = new Machine(loc: Location.EU, name: 'TarteAuPoire', profile: ['web'])
      
      def machines = [m1, m2, m3, m4, m5]
      
      def l1 = GQ {
          from p in machines
          where p.name.startsWith('Tar')
          select p.name
      }.toList()
      
      println l1
      
      def l2 = GQ {
          from p in machines
          where p.loc == Location.EU
          select p.name, p.loc.label
      }.toList()
      
      println l2

      Ce qui donne :

      [Tartanpion, Tartuffe, TarteAuPoire]
      [[Tartanpion, Europe], [Jambon, Europe], [TarteAuPoire, Europe]]

      C'est puissant..

      • [^] # Re: Compatibilité à partir du Jdk 7+

        Posté par  . Évalué à 3.

        C'est puissant..

        Je suis pas sûr de voir l'apport par rapport à une api linq/stream/etc

        https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

        • [^] # Re: Compatibilité à partir du Jdk 7+

          Posté par  (site web personnel) . Évalué à 5.

          Selon moi :

          les joins

          from n1 in nums1
          innerjoin n2 in nums2 on n1 == n2
          select n1 + 1, n2

          Et les clauses Having / Group by ( )

          from p in persons
          groupby p.gender
          having p.gender == 'Male'
          select p.gender, max(p.age)

          La syntaxe est concise et typée. Je ne suis pas expert en LINQ/Stream API, je pense que ce dernier aspect est délicat avec ces APIs. Et le tout en utilisant le Jdk 7. C'est d'ailleurs un peu comme les WhereQueries de Gorm (très ancienne), mais cette infrastructure ne fonctionne que sur les classes du domaine qui sont donc mappées dans une base de données, pas sur de simples objets en mémoire.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.