2 points par GN⁺ 2025-07-11 | Aucun commentaire pour le moment. | Partager sur WhatsApp
  • Flix est un langage orienté effets développé par Aarhus University et la communauté open source, qui combine programmation fonctionnelle, impérative et logique au sein d’un même langage
  • Son cœur est un système d’effets qui traite les effets de bord au niveau du typage, et améliore la modularité et la capacité de raisonnement grâce au suivi de la pureté, aux effets définis par l’utilisateur, aux handlers et aux reprises multiples
  • La surface du langage est étendue : types de données algébriques, pattern matching, enregistrements extensibles, traits, types de kind supérieur, types et effets associés, concurrence structurée, interopérabilité Java, et même Datalog intégré
  • La bibliothèque standard fournit plus de 3 100 fonctions et l’accès à l’écosystème Java via Maven, avec l’ambition de dépasser le cadre d’un simple langage de recherche
  • Le compilateur cible le bytecode JVM et adopte une architecture parallèle et incrémentale ; il revendique une accélération de 5x à 7x sur une machine 24 cœurs et un débit de 60 159 lines/sec sur Apple M2 Pro/OpenJDK 21

L’orientation du langage Flix

  • Flix est un langage orienté effets fondé sur des principes, qui combine programmation fonctionnelle, impérative et logique
  • Il est développé par Aarhus University et une communauté de contributeurs open source
  • Le système d’effets est un pilier des langages statiquement typés : il modélise explicitement les effets de bord afin d’aider à la modularité et au raisonnement sur les programmes
  • Les effets définis par l’utilisateur et les handlers permettent aux programmeurs d’implémenter directement leurs propres structures de contrôle
  • Parmi les langages orientés effets, Flix met en avant une implémentation aboutie, une vaste bibliothèque standard, une documentation détaillée et un bon support outillé

Types, pureté et système d’effets

  • Flix prend en charge les types de données algébriques et le pattern matching, éléments de base de la programmation fonctionnelle
  • Les tuples et les enregistrements sont pris en charge nativement ; les enregistrements utilisent un typage structurel et sont extensibles
  • Le compilateur suit précisément la pureté de toutes les expressions d’un programme
    • Si une expression est pure, il garantit qu’elle est sans effet de bord et référentiellement transparente
  • Même pour les fonctions d’ordre supérieur, la pureté est suivie grâce au polymorphisme d’effets
    • Par exemple, la pureté de List.map dépend de la pureté de la fonction f reçue en argument
  • Les effets algébriques rendent possibles les effets définis par l’utilisateur et les handlers
    • Flix prend notamment en charge les multi-shot resumptions
    • Les handlers d’effets servent à améliorer le raisonnement sur les programmes, la modularité et la testabilité

Mutations locales par région et reflet de la pureté

  • Flix prend en charge les mutations locales fondées sur des régions, ce qui permet d’utiliser en interne un état mutable et des opérations destructives tout en présentant à l’extérieur une fonction pure
  • C’est adapté aux fonctions plus naturelles à écrire avec des données mutables, ou aux cas où des structures de données mutables sont plus efficaces, comme les algorithmes de tri
  • Le reflet de la pureté est une structure de métaprogrammation dans laquelle une fonction d’ordre supérieur inspecte la pureté d’une fonction passée en argument et adapte son comportement en conséquence
    • DelayList.map change de comportement entre évaluation immédiate et évaluation paresseuse selon la pureté de la fonction argument
    • Même si une bibliothèque choisit en interne d’utiliser l’évaluation paresseuse ou parallèle, le sens observé côté client peut rester inchangé

Parallélisme, concurrence et abstraction

  • Flix facilite l’évaluation en parallèle du code pur, et permet d’écrire une implémentation parallèle de List.map avec la construction par
  • La construction par utilise en interne de légers VirtualThread
  • La concurrence structurée est prise en charge : les threads créés dans une région donnée ne peuvent pas survivre au-delà du cycle de vie de cette région
    • Dans l’exemple, deux threads sont créés dans une nouvelle région appelée rc
    • Le flux de contrôle ne quitte pas la région avant la fin des deux threads
  • Les abstractions de types prenant en charge des opérations communes utilisent des traits
    • Le trait Eq exprime la notion d’égalité et est utilisé dans toute la bibliothèque standard
  • Les types de kind supérieur permettent d’abstraire les constructeurs de types
    • Option et List implémentent tous deux Foldable
    • La bibliothèque standard inclut des traits courants comme Monoid, Functor et Foldable

Types et effets associés, et for-yield

  • Flix prend en charge les types associés, qui permettent aux types d’une signature d’instance de dépendre du type de l’instance
    • L’exemple du trait Coll permet à chaque instance de collection de définir son type d’élément via le type associé Elm
  • Les effets associés font dépendre les effets des membres d’un trait du type de l’instance
    • Il devient plus facile d’abstraire ensemble des opérations pures et avec effets, ainsi que des structures de données mutables et immuables
    • Ajouter l’effet associé Aef au trait Coll permet d’ajouter des instances de collections mutables
  • forM-yield est une structure monadique similaire aux for-comprehensions de Scala et à la notation do de Haskell
    • C’est du sucre syntaxique pour utiliser point et flatMap fournis par le trait Monad
  • forA est une expression applicative fondée sur le trait Applicative
    • Cette structure aide à écrire facilement du code de gestion d’erreurs utilisant le type de données Validation[e, t]

Interopérabilité Java et Datalog

  • Flix prend en charge l’interopérabilité Java, afin de réutiliser la Java Standard Library et le code de l’écosystème Java
    • Cela inclut l’accès à l’écosystème via Maven
    • La création d’objets, les appels de méthodes, les exceptions et l’extension de classes et d’interfaces sont pris en charge
  • La prise en charge intégrée de Datalog est l’une des fonctionnalités distinctives de Flix
    • Datalog permet d’exprimer de manière concise de nombreux problèmes de point fixe, notamment la joignabilité dans les graphes
  • Les contraintes Datalog sont des valeurs de première classe
    • Elles peuvent être passées à des fonctions ou renvoyées par celles-ci
    • Elles peuvent être stockées dans des structures de données
    • Elles peuvent être composées avec d’autres contraintes Datalog et résolues
    • Cela permet d’exprimer des familles de programmes Datalog
  • Flix prend aussi en charge les contraintes Datalog enrichies par une sémantique de treillis
    • Un exemple calcule les dates de livraison de pièces et de sous-composants
    • Une voiture dépend du châssis et du moteur, et elle peut être assemblée après l’assemblage de chaque composant
    • Les sous-composants peuvent eux aussi dépendre d’autres sous-composants, ce qui rend le problème récursif
  • Les contraintes Datalog incluant une sémantique de treillis font partie des fonctionnalités avancées de Flix et nécessitent des connaissances en théorie des treillis et en points fixes

Bibliothèque standard et liste des fonctionnalités

  • Flix inclut une bibliothèque standard fournissant plus de 3 100 fonctions
    • Le module List fournit plus de 100 fonctions
    • Le trait Foldable fournit plus de 47 fonctions
    • L’ensemble de la bibliothèque peut être exploré sur api.flix.dev
  • La liste des fonctionnalités inclut :
    • Types de données algébriques, pattern matching, fonctions de première classe
    • Enregistrements extensibles, polymorphisme paramétrique
    • Traits, types de kind supérieur, types et effets associés
    • Polymorphisme d’effets et sous-effets, reflet de la pureté
    • Concurrence de style CSP, canaux avec et sans tampon
    • Contraintes Datalog de première classe, interopérabilité Java
    • Types primitifs non boxés, syntaxe à mots-clés
    • forM, forA, holes d’expression
    • Compilation en bytecode JVM, élimination complète des appels terminaux
    • Architecture de compilateur résiliente et parallèle, erreurs lisibles par les humains

Architecture et performances du compilateur

  • Le compilateur Flix adopte une architecture résiliente, incrémentale et parallèle
  • Toutes les phases du compilateur sont parallèles, ce qui permet de tirer parti de l’accélération de chaque phase sur une machine 24 cœurs
  • Sur une machine multicœur, une accélération de 5x à 7x est possible
  • Lorsqu’un code déjà compilé est recompilé dans la même instance du compilateur, la compilation incrémentale permet d’obtenir des gains de vitesse importants
  • Les chiffres de performance sur un CPU Apple M2 Pro 10 cœurs avec OpenJDK 21 sont les suivants
    • Débit du compilateur complet : 60 159 lines/sec
    • Débit du seul front-end : 140 382 lines/sec
    • Les commandes de reproduction sont java -jar flix.jar Xperf --n 21 et java -jar flix.jar Xperf --frontend --n 21
  • Ces performances sont obtenues tout en prenant en charge des fonctionnalités de langage coûteuses comme l’inférence de types et d’effets, la monomorphisation et l’optimisation de programme entier
  • Les performances du compilateur sont principalement déterminées par les performances CPU et la bande passante mémoire

Prise en charge de Visual Studio Code et intégration des outils

  • Le compilateur Flix s’intègre à Visual Studio Code pour fournir un environnement de développement
  • L’extension VSCode utilise le véritable compilateur Flix, ce qui crée une correspondance 1:1 entre l’extension et le compilateur
    • Si VSCode ne signale pas d’erreur, c’est qu’il n’y en a pas
    • En l’absence d’erreurs, VSCode ne signale pas de fausses erreurs
  • L’extension VSCode prend en charge les fonctionnalités suivantes
    • Coloration syntaxique sémantique
    • Diagnostics d’erreurs du compilateur en ligne
    • Autocomplétion pendant la saisie, autocomplétion sensible au contexte, autocomplétion des instances de traits, complétion des holes fondée sur les types
    • Snippets et inlay hints
    • Hover affichant le type et les effets des expressions
    • Navigation vers la définition des fonctions, variables locales et enums
    • Recherche des références de fonctions, variables locales et enums, et recherche des implémentations de traits
    • Liste des symboles du document et du workspace
    • Renommage des variables locales et des fonctions
    • Exécution de main et des tests depuis l’éditeur
  • Flix intègre directement de nombreux outils dans le compilateur
    • OCaml utilise ocaml-lsp comme LSP, utop comme REPL, dune comme outil de build et opam comme gestionnaire de paquets
    • Haskell utilise HLS comme LSP, ghci comme REPL, cabal et stack comme outils de build et gestionnaires de paquets, et Hackage comme dépôt de paquets
    • Flix fournit le compilateur, le LSP, le REPL, l’outil de build et le gestionnaire de paquets via flix, et utilise GitHub comme dépôt de paquets

État du développement, cible JVM et taille du projet

  • Flix est développé et maintenu par des chercheurs en langages de programmation d’Aarhus University, au Danemark
  • Les institutions partenaires sont la University of Waterloo au Canada, la University of Tubingen en Allemagne et la Copenhagen University au Danemark
  • La participation d’une communauté mondiale de contributeurs open source augmente, et les contributions sont encouragées
  • Les statistiques du projet sont les suivantes
    • Pull Requests fusionnées : plus de 4 900
    • Issues résolues : plus de 3 100
    • Contributeurs : plus de 70
    • Base de code du compilateur : plus de 272 000 lignes
  • Flix cible la JVM
    • La JVM dispose d’implémentations open source et commerciales éprouvées, comme OpenJDK, J9, Azul et Graal
    • Elle est disponible sur Mac, Linux et Windows
    • Les JVM modernes fournissent plusieurs garbage collectors récents
    • Le support de la concurrence et du parallélisme est solide, notamment grâce aux threads légers de Java 21
    • L’écosystème fournit des outils comme des débogueurs et des profileurs
    • L’intégration Maven donne accès au riche écosystème de paquets de la plateforme Java
  • Le financement total s’élève à 1,1 million d’euros, ce qui contribue à garantir la continuité et l’indépendance du projet

Aucun commentaire pour le moment.

Aucun commentaire pour le moment.