1 points par GN⁺ 2025-10-17 | 1 commentaires | Partager sur WhatsApp
  • La version Elixir 1.19 permet de détecter davantage de bugs plus rapidement grâce à un renforcement du système de types et à des améliorations des performances de compilation
  • L’inférence de types s’étend désormais aux fonctions anonymes et aux protocoles, ce qui permet une validation automatique bien plus large sans annotations de type de l’utilisateur
  • Elle offre sur les grands projets une vitesse de compilation jusqu’à 4 fois plus élevée, avec notamment l’optimisation de la compilation parallèle et du chargement du code
  • La prise en charge d’Erlang/OTP 28 et l’introduction de la certification OpenChain renforcent aussi l’écosystème et la transparence de la chaîne d’approvisionnement
  • Elle inclut également diverses fonctionnalités comme l’amélioration de l’analyse des options, un meilleur débogage d’ExUnit et un accès plus pratique à la documentation via le shell

Principales améliorations d’Elixir 1.19

Améliorations du système de types

Inférence de types pour tous les composants

  • La type inference (inférence de types) est une fonctionnalité qui détermine automatiquement le type des expressions au moment de la compilation
  • Jusqu’à présent, l’inférence de types visait surtout les motifs, les gardes et les valeurs de retour, mais cette version introduit l’inférence de types pour tous les composants (hors gardes)
  • Comme elle s’appuie aussi sur les appels de fonctions du module et de la bibliothèque standard Elixir, des fonctions autrefois inférées comme dynamic() -> boolean() peuvent désormais l’être de façon plus précise, par exemple integer() -> boolean()
  • L’inférence de types implique plusieurs compromis liés à la vitesse de compilation, l’expressivité, la compilation incrémentale et la clarté des erreurs ; à l’avenir, elle devrait également inclure l’inférence de types des gardes ainsi que les informations de type des dépendances
  • Lorsqu’une signature de type est explicitement déclarée pour une fonction, le système n’utilise plus l’inférence mais une vérification explicite des types, afin de n’autoriser que les types conformes aux annotations de l’utilisateur

Vérification de types lors du dispatch et de l’implémentation des protocoles

  • Elixir applique désormais une vérification de types lors des appels et des implémentations de protocoles
  • Par exemple, si un type qui n’implémente pas le protocole String.Chars est transmis à une interpolation de chaîne, un message d’avertissement est affiché
  • Dans une compréhension for, un avertissement est également émis si un type ne satisfaisant pas le protocole Enumerable est passé comme générateur
  • Cette vérification de types permet d’éviter davantage de bugs dès la compilation

Inférence et vérification de types pour les fonctions anonymes

  • Elixir 1.19 prend en charge l’inférence et la vérification de types pour les fonctions anonymes
  • Par exemple, si l’on passe un type incorrect comme "hello" à une fonction anonyme qui attend un type %{}, le problème peut être détecté immédiatement sous forme de warning à la compilation
  • L’inférence de types s’applique aussi aux captures de fonctions (&String.to_integer/1, etc.), ce qui élargit le périmètre de validation automatique des types

Références et partenaires

  • Ce système de types a été développé dans le cadre d’un partenariat entre le CNRS et Remote
  • Fresha, *Starfish* *, Dashbit et d’autres ont apporté leur soutien

Compilation plus rapide sur les grands projets

Réduction des goulets d’étranglement du chargement de code

  • Auparavant, les modules étaient chargés dès leur définition, mais cette version adopte une stratégie de lazy loading (chargement différé)
  • Cela réduit la charge sur le serveur de code et améliore les performances de compilation parallèle, ce qui accélère de plus de 2 fois la compilation des grands projets
  • Deux points d’attention principaux
    • Si un processus séparé est créé pendant la compilation pour accéder à des modules du même projet, certains chargements peuvent manquer ; on peut contourner cela avec Kernel.ParallelCompiler.pmap/2 ou Code.ensure_compiled!/1
    • Dans un callback @on_load, l’appel à un module du même projet peut provoquer une erreur ; si nécessaire, on peut utiliser l’option @compile {:autoload, true}
  • Dans les deux cas, des erreurs de compilation non déterministes pouvaient autrefois se produire, mais cette amélioration garantit désormais un environnement de compilation déterministe (reproductible)

Compilation parallèle des dépendances

  • Elixir prend en charge la compilation parallèle des dépendances (dependencies) via la variable d’environnement MIX_OS_DEPS_COMPILE_PARTITION_COUNT
  • Comme plusieurs processus OS peuvent compiler les dépendances en parallèle, les performances de compilation peuvent être améliorées jusqu’à 4 fois selon la taille du projet et le nombre de cœurs CPU
  • À titre expérimental, définir une valeur correspondant à environ la moitié des cœurs disponibles est jugé efficace pour l’utilisation des ressources
  • Comme la parallélisation peut augmenter l’utilisation mémoire, il faut être prudent lors d’un déploiement sur un serveur de build ou dans un environnement CI

Prise en charge d’Erlang/OTP 28

  • Elixir 1.19 prend officiellement en charge Erlang/OTP 28.1+
  • En raison du changement de représentation des expressions régulières dans Erlang/OTP 28, il n’est plus possible d’utiliser des expressions régulières comme valeur par défaut dans une struct
  • Il reste toutefois possible d’utiliser des expressions régulières lors de l’initialisation d’une struct

Introduction de la certification OpenChain

  • Cette version est la première à entamer la conformité à la spécification OpenChain
  • Chaque release inclut une SBoM (Source Bill of Materials) au format CycloneDX 1.6/SPDX 2.3
  • Cela renforce la transparence de la chaîne d’approvisionnement concernant les composants et les licences de la release, tout en contribuant à une gestion plus stricte
  • Ce travail a été réalisé par Jonatan Männchen avec le soutien de l’Erlang Ecosystem Foundation

Autres améliorations

  • Diverses améliorations d’outils et de bibliothèques ont été ajoutées, notamment pour l’analyse des options, le débogage et les performances d’ExUnit, ainsi que l’accessibilité de la documentation via le shell
  • Pour des notes de version plus détaillées, consulter le CHANGELOG

1 commentaires

 
GN⁺ 2025-10-17
Avis Hacker News
  • Il est souligné que l’introduction progressive de la vérification automatique des types dans Elixir constitue un excellent exemple d’évolution de langage dont d’autres langages de programmation pourraient s’inspirer ; beaucoup de langages ont déjà vu leur écosystème se scinder en deux à cause de grands changements, alors qu’avec Elixir, José a clairement indiqué dès 2018 que le langage lui-même était achevé, ce qui est rassurant. Le langage et son cœur ne vont plus subir de ruptures, ce qui apporte une grande stabilité. La vidéo de présentation associée est recommandée. Impressionné par cette gestion cohérente et exemplaire

    • Comme exemples majeurs de fragmentation d’écosystème causée par de grands changements, seuls Python 3 et Perl 6 viennent vraiment à l’esprit. Le choc provoqué par ces deux transitions a sans doute fait paraître les autres évolutions de langage énormes elles aussi
    • Avec Elixir, on n’a jamais l’impression d’être constamment forcé de courir après les montées de version ; on observe les changements introduits, puis on a envie de mettre à jour pour profiter de nouvelles fonctionnalités utiles. On ne ressent ni l’anxiété ni le stress qu’on a quand on vous impose un changement de version à marche forcée
    • J’utilise Elixir en production depuis 2017, et à chaque mise à jour, tout s’est déroulé bien plus facilement que prévu. En réalité, ce sont souvent les mises à jour d’Erlang/OTP qui se sont révélées plus complexes à cause de problèmes de compatibilité ; c’est pourquoi j’utilise généralement la dernière version d’Elixir, tout en attendant un ou deux mois de plus avant de mettre à jour OTP, le temps que les éléments conflictuels soient corrigés
    • Elixir reste encore un peu immature et manque parfois de commodité ; il lui faut des guides clairs pour atteindre ses objectifs et une stabilisation de l’écosystème. Beaucoup de packages sont abandonnés ou mal documentés, ce qui rend difficile le suivi du rythme d’évolution de l’écosystème Phoenix. Beaucoup d’utilisateurs ne veulent pas de LiveViews ni de certains systèmes de composants, et la barrière d’entrée pour la compatibilité avec d’autres outils et technologies reste élevée. Python 3 nécessitait absolument une transition depuis Python 2 et s’en est relativement bien sorti grâce à des outils de migration automatisés, malgré de nombreux tâtonnements. Ruby 3, en revanche, a plutôt semé la confusion avec l’introduction de fichiers de types externes et la fragmentation des outils ; entre le boilerplate, les problèmes de gouvernance et même des détournements de gems, l’expérience a été suffisamment négative pour me détourner de Ruby. Même un excellent langage peut être ruiné par une gouvernance immature : une collaboration mature, une bonne communication et une gestion du changement de qualité sont essentielles. Les évolutions de design de langage doivent être largement expérimentées en amont, conduites avec prudence, et annoncées suffisamment tôt aux utilisateurs afin de limiter au maximum la confusion inutile. J’espère qu’Elixir/Phoenix/OTP deviendra encore plus simple, puissant, productif et performant, afin que des profils d’utilisateurs variés puissent l’adopter sereinement. Recommandation de ressources comme Livebook et le parcours Elixir d’Exercism
  • Elixir continue d’apporter d’excellentes fonctionnalités et améliorations, tout en évoluant de manière stable. La structure du langage est remarquable et ses créateurs gardent constamment le cap dans la bonne direction, ce qui est vraiment impressionnant. Le seul regret, c’est de ne pas avoir plus souvent l’occasion d’utiliser Elixir au quotidien

    • J’avais tellement envie d’utiliser Elixir que j’ai même quitté mon entreprise pour lancer ma propre startup
  • Partage de données expérimentales sur la vitesse de compilation des dépendances Phoenix : sur un Mac M1 Max, avec une petite application ne contenant que les dépendances Phoenix de base, les temps de compilation suivants ont été mesurés selon la valeur de la variable d’environnement MIX_OS_DEPS_COMPILE_PARTITION_COUNT

    PARTITION_COUNT=1:  12.336초 (유저 32.30s, 시스템 7.23s, CPU 320%)
    PARTITION_COUNT=5:  6.970초 (유저 0.37s, 시스템 0.49s, CPU 12%)
    PARTITION_COUNT=10: 7.236초 (유저 0.38s, 시스템 0.50s, CPU 12%)
    

    Le cache a été supprimé entre chaque essai avec la commande rm -rf _build

    • Les exécutions suivantes semblent avoir été mesurées avec le cache actif ; la compilation native s’est peut-être faite directement dans le dossier dep, sans laisser de traces dans _build
    • Je ne comprends pas pourquoi les résultats de benchmark sur cette fonctionnalité de la release se font downvoter ; si quelqu’un peut donner son avis, je suis preneur
  • J’ai vraiment commencé à adorer Gleam ces derniers mois. L’arrivée du système de types dans Elixir est bienvenue, mais c’était auparavant l’un des principaux freins à son adoption pour moi. J’aimerais réessayer Elixir un jour, mais je crains un système à la TypeScript, typé en apparence seulement, où dans la pratique beaucoup de bibliothèques ou packages finissent simplement en types dynamiques ou any. Je me demande si cette inquiétude est infondée. BEAM est vraiment excellent

    • Le contexte est différent de TypeScript. Grâce au pattern matching, il devrait être possible d’inférer les types sur au moins 50 % d’une base de code Elixir existante, et comme Elixir standard fournit nativement les types, les projets maintenus devraient se typer rapidement. Je ne suis pas particulièrement partisan des systèmes de types et j’utilise surtout JS, mais dans Elixir, l’ajout des types se fait naturellement ; là où TypeScript remonte vers le haut, Elixir semble se propager naturellement vers le bas
    • Gleam ne permet pas de profiter pleinement des véritables forces d’OTP/BEAM ; c’est un attrait qu’Elixir seul offre vraiment
    • Elixir dispose depuis longtemps de concepts de types via les types primitifs, les structs et la déstructuration basée sur la shape ; il est déjà possible d’y faire de la vérification de types avec des outils comme Dialyzer ou TypedStruct. Ce n’est pas un langage absurdement non typé comme JavaScript
    • Gleam est bien, mais sur la JVM, Kotlin est aussi un langage typé à la syntaxe proche de Ruby, avec en plus la possibilité de compiler vers JS
  • Elixir donne l’impression d’être l’environnement le plus prometteur pour le développement web. Chaque fois que je rencontre une organisation ou une équipe qui utilise Elixir dans un contexte professionnel, leur niveau me paraît supérieur à la moyenne. Dans des environnements qui exigent un développement continu, Elixir semble continuer à fournir une direction et des standards

  • Cette release d’Elixir commence à prendre en charge les formats Source SBoM CycloneDX 1.6+ et SPDX 2.3+. C’est vraiment appréciable de voir la gestion des SBOM prise en charge au niveau du langage. Dommage que mon entreprise n’utilise pas Elixir actuellement

  • Si vous voulez contribuer à un projet open source Elixir utilisé en conditions réelles, un composant majeur de l’ancien Mozilla Hubs continue d’être développé en Elixir dans un projet indépendant : voir Hubs Foundation/reticulum

  • Avec la bibliothèque standard d’Elixir, il est possible de faire à la compilation de l’inférence de types adaptée au contexte de l’application, par exemple depuis un type dynamique vers booléen, ou d’un entier vers booléen

  • Je n’ai pas d’expérience de développement en Elixir, mais j’en suis fan. J’aimais autrefois le pragmatisme et l’élégance de Ruby, puis je me suis tourné vers d’autres langages en découvrant l’attrait des systèmes de types. Elixir et Ruby ont tous deux introduit un système de types, mais aujourd’hui j’utilise surtout Kotlin, qui donne syntaxiquement l’impression d’un « Ruby typé »

    • Kotlin ressemble presque à ce que nous attendions vraiment de jruby
  • J’utilise Soketi avec le SDK pusher pour gérer la diffusion d’événements. L’application mélange des endpoints temps réel et des endpoints REST ; la charge de calcul temps réel n’est pas énorme, mais si besoin je compte la traiter séparément en Go. Nous allons aussi bientôt ajouter des fonctionnalités collaboratives ; dans ce contexte, je me demande si adopter Phoenix est la bonne décision