Greboca  

Suport technique et veille technologique

Aujourd’hui, les grandes entreprises et administrations publiques hésitent entre continuer à utiliser des logiciels propriétaires ou basculer vers les Logiciels Libres. Pourtant, la plupart des logiciels libres sont capables de bien traiter les données issues des logiciels propriétaire, et parfois avec une meilleur compatibilité.

C’est alors la barrière de la prise en main qui fait peur, et pourtant...

Les logiciels libres

L’aspect « Logiciel Libre » permet une évolution rapide et une plus grande participation des utilisateurs. Les aides et tutoriels foisonnent sur Internet ou sont directement inclus dans le logiciel lui-même.

Enfin, les concepteurs sont plus proches des utilisateurs, ce qui rend les logiciels libres plus agréable à utiliser et conviviaux.

Grâce à la disponibilité des logiciels libres, vous trouverez facilement des services de support techniques et la licence n’est plus un frein à l’utilisation de ces logiciels par votre personnel.

Notre support technique concerne essentiellement les logiciels libres, que ce soit sous forme de services ponctuels ou de tutoriels.

LinuxFr.org : les journaux  -  Dhall, une réponse au problème de configuration

 -  Mai 2020 - 

Sommaire

Cher Journal,

Ne te fie pas à l’intitulé, « le problème » n’est qu’un condensé fourre-tout pour ce qui est connu en tant que “Software Configuration Management issues” dans la lingua veicolare de la sphère informatique. Quant à Dhall, il s’agit d’un langage spécialisé dans la gestion de configurations1.

Présentation

Condensé en deux ou trois paragraphes

Dhall est un outil primordialement destiné à programmer les fichiers de configuration. En acronymes de moins de cinq lettres, tu as certainement entendu parler de formats comme INI, XML, JSON, YAML, TOML. Ils ont le point commun de ne pas être programmable. Différents degrés de programmabilité présentent différents atouts, entre autres la réduction des répétitions, la réutilisation ailleurs de portions produites dans un endroit initial, …

Un fichier .dhall à la fois exprime de la configuration et constitue une expression dans le langage de programmation Dhall. Cette expression sera in fine réduite, normalisée, après un processus d’évaluation, lequel processus est garanti de prendre cours pendant un temps fini. Par conséquent, peu importe l’expressivité, la technicité, … d’une expression Dhall, elle finira par être aplatie sous forme de valeurs basiques, id est telles que définies par le standard. Les expressions sont typées et les types standard dans la version actuelle sont sommairement listés ici-bas.

  1. Bool : booléens
  2. Natural : nombres entiers naturels (positifs, non-signés)
  3. Integer : nombres entiers signés
  4. Double : nombres décimaux
  5. Text : du texte
  6. List : tableaux, listes chaînées de valeurs partageant le même type
  7. Optional : variants, sommes
  8. Record : produits

En plus des types, le langage

  • permet d’exprimer des expressions intermédiaires sous forme de let … in ….
  • est muni d’une bibliothèque standard.

Caractéristiques conceptuelles

L’auteur originnel est Gabriel GONZALEZ (lien en HTTP) et certains choix reflètent des idées qui lui sont chères. Néanmoins, beaucoup d’autres personnes ont contribué au langage depuis son inception et cette sous-section se contentera de faire des constats sans chercher à les attribuer à Gabriel et ali.

Dhall a un typage fort et statique : une expression est correctement typée ou ne l’est pas et cela se voit très tôt ; il n’y a pas de contournements possibles pour essayer de retarder la vérification de types. Cela étant dit, tout est abondamment documenté, même les erreurs. La manière dont le langage évolue (quelle variété de typage, quelle fonction, … ajouter) ne dépend pas tant des avancées dans les systèmes de types, mais plutôt de la motivation plus ou moins avouée de la communauté autour : remplacer les systèmes de configurations non-programmables les plus en vogue, nommément JSON, YAML et TOML. Eh oui, mon journal, Gabriel et ali ont des opinions ! Ces soubassements dévoilés, il sera plus compréhensible de voir le foisonnement d’exemples liés à JSON et YAML dans diverses pages de la documentation upstream.

Un des choix prépondérant du langage est la limitation explicite des opérations possibles sur du texte. Plus précisément, une seule opération est permise : la concaténation. Ainsi ne peut-on pas comparer deux valeurs de types Text ou en calculer la taille en caractères. Encore une fois, derrière ce choix se trouve l’accent mis sur la capacité de bannir des catégories d’erreurs dès la vérification de types.

Un autre choix de poids garantit que tout opérateur

  1. est associatif, c'est-à-dire qu’il est superflu de préciser la priorité selon laquelle ses arguments seront évalués; par exemple, si a est de type Natural (a : Natural) ainsi que b : Natural et c : Natural, alors on peut additionner les trois avec l’opérateur + en faisant (a + b) + c ou a + (b + c) et les deux expressions équivalent à a + b + c.
  2. est muni d’une valeur nulle, un élément neutre, un zéro, valable dans toute l’étendue du type pour lequel il est défini. Exemples sous la notation (opérateur, zéro):
  • (*, 1) dans Natural et Integer,
  • (∧, {=}) dans Record,
  • (==, True) dans Boolean.

Derrière ces restrictions se trouve la nécessité de garantir que le résultat de l’application d’un opérateur aura le même type que les arguments qui y auront contribué ; c’est une nécessité propre à Dhall … J’ai mentionné plus haut qu’il est impossible de comparer deux valeurs de type Text ; cela est ainsi parce que (a : Text) == (b : Text) donnerait un c : Bool, une valeur de type différent de celui des valeurs de départ.

Puisqu’on parle de fichiers de configuration, il sautera aux yeux que ces restrictions sont incompatibles avec la manière dont on conçoit les tableaux associatifs ou dictionnaires, structures de données omniprésentes dans les configurations : avant de modifier de telles structures, des comparaisons d’égalité s’imposent. Un examen attentif du type Record couplé avec des fonctions de la bibliothèque standard permettent de lever l’apparente rigidité du langage.

Syntaxe et exemple plutôt dépouillé

Persée, Dictys, et Méduse forment une équipe chargée d’assurer les cours à distance d’une classe covid-confinée. Cassiopée est en charge de l’infrastructure sur laquelle tout cela reposera et, pour diverses raisons, décide que chaque membre du triptyque devrait avoir une configuration afin de garantir les conditions suivantes.

  • Pour un jour donné, indiquer une plage horaire pendant laquelle ses activités seront accomplies.
  • Énoncer d’emblée quels sont les thèmes que son cours abordera.
  • Déposer des documents supplémentaires potentiels et laisser Cassiopée en faire la distribution à l’audience.

Cassiopée est bien sûr Dhall-iste, découpe temporellement les choses en termes de semaines et prototype ses actions ainsi (juste un extrait) :

-- Fichier: a.dhall
{
      semaine   : Natural
    , personnel : List Text
}

Comme indiqué précédemment, le type d’une valeur est indiqué par deux points. Les annotations de types ne sont pas partout requis, Dhall inférant les types pour tous les cas non-ambigus ou non-spéciaux. Tout ce qui est dans ce fichier a.dhall est facultatif à Dhall mais est aussi valide. semaine est un nombre entier naturel, personnel un tableau dans lequel chaque élément est une valeur textuelle. Remarquons que

  • l’expression finale est une valeur anonyme de type Record, ce qu’indique les accolades ;
  • l’indentation est laissée à l’appréciation de tout le monde ;
  • les commentaires mono-lignes sont préfixées par deux tirets successifs.

Pour évaluer le fichier, utilisons par exemple le binaire dhall dans le Shell (Bash de ce côté ; les sorties sont en commentaires) :

dhall --file 'a.dhall'
# {  personnel : List Text, semaine : Natural }

Au lieu de types, traitons de valeurs.

-- Fichier: b.dhall
let per = "Persée" 
let dic = "Dictys" : Text

in {
      semaine   = 20
    , personnel = [per, dic, "Méduse"]
}

dhall dit que nous sommes toujours dans les clous:

dhall --file 'b.dhall'
# { personnel = [ "Persée", "Dictys", "Méduse" ], semaine = 20 }

dhall --annotate --file 'b.dhall'
#   { personnel = [ "Persée", "Dictys", "Méduse" ], semaine = 20 }
# : { personnel : List Text, semaine : Natural }

Constatons que l’évaluation a normalisé les entrées puisqu’en plus de la suppression du commentaire, les indirections let … in ont également disparues. L’expression reste une valeur anonyme de type Record. let introduit des variables visibles à l’intérieur de in.

Pour en finir avec cette démo, parlons des fonctions. La syntaxe à la Curry, le calcul lambda — ou toute autre expression par laquelle, ô journal !, tu serais déjà accoutumé à ce qui suit — alors, cette syntaxe permet de considérer que n’importe quelle fonction possède un seul argument. S’il y en a effectivement un, tant mieux, on l’applique: fct arg : ceci est un appel de la fonction fct sur le paramètre arg. S’il y en a plusieurs, on applique le premier argument à la fonction et on retourne une fonction anonyme qui prendra le reste des arguments et continuera le processus d’applications jusqu’à l’aboutissement d’une forme aplatie, normalisée. Le Robert me dit qu’un péquin est une personne quelconque, une personne lambda; par analogie, une fonction quelconque, anonyme, est aussi appelée fonction lambda. Voyons où ce détour nous mène :

-- Fichier: c.dhall
let precedemment   = ./b.dhall
let dossier_global = "/home/cours/"
let creer_dossier  = λ(val : Text)  dossier_global ++ val ++ "/"
let ajouter_theme  = λ(ind : Text)  λ(thm : Text)  creer_dossier ind ++ thm

in
    { thematiques =
        [ creer_dossier "Persée"
        , creer_dossier "Dictys"
        , ajouter_theme "Méduse" "Que racontait Zarathoustra ?" ]

    }  precedemment
  • precedemment a capturé une ressource, une URI. Ici, c’était un fichier indiqué par un chemin relatif. La ressource pouvait aussi être adressée par un chemin absolu ou une URL sur le WWW ; dans ce dernier cas, l’évaluation de l’expression aurait nécessité de la connexion Internet.
  • creer_dossier est un synonyme à la fonction lambda qui prend un seul argument et y applique deux concaténations grâce à l’opérateur ++.
  • ajouter_theme est un synonyme à une autre fonction anonyme qui prend deux arguments et fait usage de la fonction creer_dossier.
  • Le Record anonyme en cours de création est concaténée au Record créé ailleurs, dans le fichier b.dhall. La fusion des deux est accomplie par l’application de l’opérateur .
  • L’usage de l’Unicode est laissée à l’appréciation de tout le monde.
  • L’expression finale est celle-ci:
dhall --file 'c.dhall'
# { personnel = [ "Persée", "Dictys", "Méduse" ]
# , semaine = 20
# , thematiques =
#   [ "/home/cours/Persée/"
#   , "/home/cours/Dictys/"
#   , "/home/cours/Méduse/Que racontait Zarathoustra ?"
#   ]
# }

dhall type --file 'c.dhall'
# { personnel : List Text, semaine : Natural, thematiques : List Text }

Bref, nous avons obtenu un tout-bête fichier de configuration. Qu’en est-il des plages horaires et les plans sur la comète de Cassiopée ? Ah, journal !, tu l’as vu venir : « Cela est laissé en tant qu’exercice … »

Cette sous-section a commencé en attribuant toutes les choses qui allaient apparaître à Cassiopée ; je tiens à préciser que tout malentendu, toute imprécision ne sont dus qu’à moi ; Cassiopée, Dhall, … sont quittes.

Implémentations et interopérabilité

Un langage qui ne cache pas vouloir en remplacer d’autres doit se doter d’outils de migration. Sans même parler de migration, ces outils permettent de juste satisfaire la curiosité de personnes qui sont habituées à autre chose. Dans cette optique, il existe un certain nombre de binaires et bibliothèques qui effectuent la conversion dhall-to-FOO ou Foo-to-dhall. En témoin ces deux-là :

  • YAML: dhall-to-yaml --file 'c.dhall'
personnel:
  - "Persée"
  - Dictys
  - "Méduse"
semaine: 20
thematiques:
  - "/home/cours/Persée/"
  - /home/cours/Dictys/
  - "/home/cours/Méduse/Que racontait Zarathoustra ?"
  • JSON: dhall-to-json --file 'c.dhall'
{
  "personnel": [
    "Persée",
    "Dictys",
    "Méduse"
  ],
  "semaine": 20,
  "thematiques": [
    "/home/cours/Persée/",
    "/home/cours/Dictys/",
    "/home/cours/Méduse/Que racontait Zarathoustra ?"
  ]
}

Il y a même un dhall-to-yaml-ng produisant une autre variété de YAML.

Dhall a un standard et des implémentations diverses. À cette date, il y en a de matures en Clojure, Eta, Haskell, Java, Go, Nix, Ruby, et Rust.

Quant à la portabilité du langage sur des architectures matérielles, j’invoquerai un seul mot: Go. Une norme qui est implémentée dans ce langage se voit de facto portée sur une galaxie d’architectures. Je te vois venir, journal ! Je suis d’accord avec toi sur les problématiques liées à la taille et la puissance de Google ; à vrai dire, mon Go-innumérisme est même immensurable. Cependant, le binaire go qui se trimbale sur cette machine dit des choses que je ne peux pas ignorer :

# Combien d’architectures supporte golang?
go tool dist list | wc --lines
# 43

Dans la liste des implémentations, il y a Nix, un langage et ensembles d’outils qui sont, disons, des super-ensembles de Dhall à maints égards. Ça mérite une mention mais je préfère ne pas ouvrir un autre potentiel front après Go …

Approfondir le sujet

Voici une collection de liens triés subjectivement par ordre décroissant de pertinence :

Gabriel dira à qui veut entendre que Dhall est Turing-incomplet. Pourquoi insister ? Voici en HTTP ce qu’il a à dire sur ce sujet.

Par ailleurs, d’aucuns diront que YAML est bien comme il est, n’est-ce pas ? Et si on adoptait une approche diamétralement opposée en se débarrassant complètement des fichiers de configuration ? Il se trouve que nous avons des langages de programmation pour … programmer, notamment les fichiers de configurations. Et toi, journal, penses-tu que, sic, “[…] configs suck?”


  1. J’ai commis ce texte sous CC by SA 4.0 

Commentaires : voir le flux atom ouvrir dans le navigateur

par gipoisson

LinuxFr.org : les journaux

LinuxFr.org : Journaux

firefox, nouvelle fenêtre dans une session isolée

 -  15 avril - 

Les fenêtres de navigation privées de firefox partagent leurs cookies de session or je souhaitais avoir des fenêtres de navigation isolées, (qui ne (...)


Pretendo tente de déprogrammer l'obsolescence des consoles Nintendo

 -  9 avril - 

Ah Nal,Gros N vient de faire un gros doigt aux utilisateurs de ses consoles 3DS et Wii U en annonçant la fermeture des services en ligne pour (...)


[Trolldi] Vulgarisation sur l'IA pour décideur pressé

 -  5 avril - 

Cher 'Nal,Je fais un article-marque-page sur un post tout frais de Ploum où il est question d'un fantasme vieux comme le Talmud avec le Golem. (...)


Super Marian and Robin: les roms en collant

 -  3 avril - 

Bonjour Nal,Je t'écris pour te proposer de tester mon nouveau jeu: Super Marian and Robin.Il s'agit d'un jeu de plateformes pour un ou deux (...)


Le roi est mort, vive le roi ! Les alternatives de Redis sont là

 -  3 avril - 

Bonjour Nal !Après le changement de licence de Redis, ce qui devait arriver arriva, et des alternatives libres apparaissent.Tout d'abord, on a (...)