URL: https://linuxfr.org/news/ocaml-en-2021 Title: OCaml en 2021 Authors: octachron Yves Bourguignon, chimrod, Ysabeau đŸ§¶, Snark, BenoĂźt Sibaud, Anonyme, Bruno Ethvignot, Quidam, syntaxerror, MichaĂ«l, dourouc05 et tisaac Date: 2021ćčŽ01月12æ—„T16:25:31+01:00 License: CC By-SA Tags: ocaml Score: 58 La version 4.13.0 du langage OCaml est sortie le 24 septembre 2021, sept mois aprĂšs OCaml 4.12.0 sortie le 24 fĂ©vrier 2021. OCaml est un langage fonctionnel de la [famille des langages ML](https://fr.wikipedia.org/wiki/ML_(langage)) (dont font partie SML et F#). Il s’agit d’un langage fonctionnel multi‐paradigme fortement typĂ© qui permet de mĂ©langer librement les trois paradigmes : fonctionnel, impĂ©ratif et objet. La plus grande spĂ©cificitĂ© d’OCaml dans le paysage des langages fonctionnels (Haskell, Rust, F#...) est probablement son systĂšme de module : les modules d’OCaml font partie intĂ©grante du langage, et il est par exemple possible de dĂ©crire des modules paramĂ©trĂ©s par d’autres modules (Ă  travers des [foncteurs](https://ocaml.org/manual/moduleexamples.html#s%3Afunctors)). La grande nouveautĂ© de cette annĂ©e 2021 est la convergence de l’environnement d’exĂ©cution entre la version standard d’OCaml et le prototype d’OCaml multi-cƓur. Cette convergence amorce une nouvelle Ă©tape dans la transition vers OCaml multi-cƓur. Au-delĂ  des progrĂšs vers OCaml multi-cƓur, cette annĂ©e 2021 a vu une de nombreuses avancĂ©es pour le langage OCaml et son compilateur que ce soit en termes d’architectures supportĂ©es, de messages d’erreurs, de fonctionnalitĂ©s du systĂšme de types, mais aussi des amĂ©liorations de confort pour les programmeurs que ce soit au niveau des outils de profilage, de la gestion des avertissements ou de la bibliothĂšque standard. ---- [Site officiel](https://ocaml.org) [Manuel de rĂ©fĂ©rence d'OCaml](https://ocaml.org/manual) [ocamlverse](https://ocamlverse.github.io/) [Forum officiel](https://discuss.ocaml.org/) [Changelog](https://github.com/ocaml/ocaml/blob/4.13/Changes) ---- # La route vers le multi-cƓur et OCaml 5.0 Une des limites de l’implĂ©mentation actuelle de l’environnement d’exĂ©cution d’OCaml est son utilisation d’un verrou global. Ce verrou empĂȘche les applications _multithreads_ de bĂ©nĂ©ficier du parallĂ©lisme des fils d’exĂ©cution (_threads_). Au cours du temps, il y a eu plusieurs tentatives d’enlever ce verrou. La derniĂšre initiative a germĂ© chez OCaml Labs vers 2014-2015. Pour Ă©viter les Ă©checs prĂ©cĂ©dents, cette initiative a dĂ©cidĂ© de se concentrer sur deux points : une compatibilitĂ© descendante presque parfaite avec la version monocƓur d’OCaml, et une intĂ©gration incrĂ©mentale dans la branche principale d’OCaml. Ce travail de fond a commencĂ© Ă  ĂȘtre visible dans OCaml 4.10.0. Mais il s’est notablement accĂ©lĂ©rĂ© dans OCaml 4.12.0. Une grande partie du travail dans OCaml 4.12 et 4.13 a Ă©tĂ© consacrĂ©e Ă  diminuer les divergences entre l’environnement d’OCaml multi-cƓur et la version principale d’OCaml. Par exemple, un des changements majeurs prĂ©vus pour OCaml multi-cƓur est la gestion des pointeurs pointant en dehors de la mĂ©moire gĂ©rĂ©e par OCaml, sans ĂȘtre gardĂ©s par des mĂ©tadonnĂ©es (parce que, par exemple, ils ont Ă©tĂ© allouĂ©s par une bibliothĂšque C externe). Dans la version monocƓur d’OCaml, ces pointeurs Ă©taient gĂ©rĂ©s en gardant une trace des zones mĂ©moires allouĂ©es par OCaml. En passant Ă  un environnement d’exĂ©cution multi-cƓur, cette stratĂ©gie devient prohibitive en coĂ»t de synchronisation. Ces pointeurs nus ne seront donc pas autorisĂ©s dans OCaml multi-cƓur. Pour assurer une Ă©volution en douceur, OCaml 4.12.0 a ajoutĂ© deux options de configuration : une option pour dĂ©sactiver la gestion des pointeurs nus directement pour les audacieux ; et une version plus prudente qui rajoute un test dynamique de la prĂ©sence de ces pointeurs nus. Cette derniĂšre option est notamment utilisĂ©e pour tester toutes les bibliothĂšques et programmes disponibles sur Opam (le dĂ©pĂŽt de paquets d’OCaml). Un autre point important est la gestion de l’ordonnancement entre l’utilisateur et l’environnement d’exĂ©cution (_runtime_). Dans la version monocƓur d’OCaml, l’environnement d’exĂ©cution reprend la main Ă  chaque allocation. Cela lui donne l’occasion de vĂ©rifier si le Glaneur de Cellules (GC) Ă  du travail Ă  faire, ou s’il faut s’occuper de signaux en attente. Une consĂ©quence est qu’il est possible d’écrire du code numĂ©rique qui n’alloue jamais et ne rend jamais la main Ă  l’environnement d’exĂ©cution. En absence de parallĂ©lisme, ce comportement est plus une curiositĂ© qu’autre chose. Mais pour multi-cƓur OCaml, ce comportement Ă©goĂŻste n’est plus de mise. Dans sa conception actuelle, OCaml multi-cƓur a une phase de GC en parallĂšle, pendant laquelle tous les fils d’exĂ©cution exĂ©cutent une passe de GC de maniĂšre synchrone. Il n’est donc pas question qu’un fil d’exĂ©cution bloque le GC de tous les autres fils. Le compilateur natif a donc Ă©tĂ© modifiĂ© dans OCaml 4.13.0 pour s’assurer qu’un fil d’exĂ©cution passe toujours la main Ă  l’environnement d’exĂ©cution dans un temps bornĂ©. Un Ă©lĂ©ment qui commence Ă  apparaĂźtre dans les discussions sur OCaml multi-cƓur est que l’on se rapproche d’un point oĂč il ne reste plus qu’à faire le grand saut et intĂ©grer le _runtime_ multi-cƓur, et absorber les petites pertes de performances inĂ©vitables pour le code sĂ©quentiel. La premiĂšre version d’OCaml qui intĂ©grera la prise en charge du multi-cƓur sera OCaml 5.0. Cette nouvelle majeure commencera avec une pĂ©riode de transition durant laquelle la branche 4 sera maintenue activement. Cette premiĂšre version d’OCaml multi-cƓur n’intĂšgrera pas la partie la plus innovante de la proposition initiale, le systĂšme d’effet, et se contentera d’exposer une bibliothĂšque de domaines et quelques API de plus haut niveau, bĂątis au-dessus de cette bibliothĂšque de domaine. Le but est de dĂ©coupler la partie _runtime_ du dĂ©veloppement d’OCaml multi-cƓur du travail de conception sur le systĂšme d’effet qui requiert encore des efforts de conception. # Une prise en charge Ă©tendue de RISC-V Ă  macOS/ARM64 Le compilateur OCaml gĂšre deux modes de compilation : un mode _bytecode_ qui fonctionne sur toute architecture oĂč un compilateur C est disponible ; et un mode natif qui Ă©met directement des binaires natifs. Ce mode natif est d’ailleurs le seul utilisateur du systĂšme objet d’OCaml au sein du compilateur lui-mĂȘme. Cette gestion native requiert de s’adapter aux nouvelles familles de processeurs et aux variations d’ABI suivant les systĂšmes d’exploitation. OCaml 4.11.0 a ainsi vu apparaĂźtre la prise en charge du RISC-V sous Linux. De maniĂšre similaire, la prise en charge prĂ©-existante pour ARM64 a Ă©tĂ© Ă©tendue pour couvrir les conventions d’appels de macOS dans OCaml 4.12.0 . # De meilleurs messages d’erreurs Écrire des messages d’erreurs utiles est une tĂąche plus difficile qu’il n’y paraĂźt. Il peut ĂȘtre tentant de communiquer une erreur interne sur l’implĂ©mentation ou d’évoquer une thĂ©orie avec laquelle l’utilisateur n’est pas familier. Un autre problĂšme assez frĂ©quent pour les erreurs de types dans OCaml est que le vĂ©rificateur de type est optimisĂ© pour vĂ©rifier rapidement que le code est bien typĂ©. Avec ce mode de fonctionnement, on ne dĂ©couvre parfois une erreur uniquement aprĂšs qu’une sĂ©rie de petites erreurs nous ait menĂ© Ă  une situation impossible. En bref, il reste pas mal de travail Ă  faire pour amĂ©liorer les messages d’erreurs d’OCaml. Mais cette annĂ©e 2021 a vu quelques progrĂšs intĂ©ressants, et d’autres sont dĂ©jĂ  intĂ©grĂ©s ou en cours d’intĂ©gration dans la version de dĂ©veloppement d’OCaml. ## Des messages d’erreurs plus dĂ©taillĂ©s pour les foncteurs Les foncteurs sont des fonctionnalitĂ©s uniques d’OCaml. Ils permettent de dĂ©crire des modules qui dĂ©pendent d’autres modules. Par exemple, la dĂ©finition d’un module `Graphe` peut prendre comme argument un module `Sommet` et un module `Arete` : ```ocaml module Graphe(Sommet:SOMMET)(Arete:ARETE) = struct ... end ``` Je peux ensuite instancier ce foncteur avec diverses implĂ©mentations de `ARETE` et `SOMMET`. Par exemple : ```ocaml module Graphe_basique = Graphe(Sommet_basique)(Arete_basique) module Graphe_colore = Graphe(Sommet_colore)(Arete_basique) ``` Cette formulation en termes de foncteur permet de dĂ©crire des algorithmes de graphes indĂ©pendamment de l’implĂ©mentation des arĂȘtes ou sommets (sont-ils nommĂ©s ? colorĂ©s ?). Avant OCaml 4.13, les erreurs liĂ©es Ă  ces foncteurs pouvaient ĂȘtre trĂšs verbeuses. Par exemple, si j’applique le foncteur `Graphe` avec un argument en trop : ```ocaml module G = Graphe(Etiquette)(Sommet)(Arete) ``` Le vĂ©rificateur de type d’OCaml se plaignait que le module Etiquette n’est pas un `SOMMET`, ce qui donne un message d’erreur qui ressemble Ă  cela : ``` Modules do not match: sig type t = string end is not included in SOMMET The value `label' is required but not provided The value `create' is required but not provided The type `label' is required but not provided The value `equal' is required but not provided The value `hash' is required but not provided The value `compare' is required but not provided ``` Avec OCaml 4.13.0, le vĂ©rificateur de type prend de la hauteur et essaye d’identifier des erreurs de haut niveau dans les erreurs liĂ©es aux foncteurs : est-ce que l’utilisateur n’aurait pas oubliĂ© un argument ? AjoutĂ© un argument ? ModifiĂ© quelques arguments ? ``` Error: The functor application is ill-typed. These arguments: Etiquette Sommet Arete do not match these parameters: functor (Sommet : SOMMET)(Arete : ARETE)} -> 1. The following extra argument is provided Etiquette : sig type t = string end 2. Module Sommet matches the expected module type SOMMET 3. Module Arete matches the expected module type ARETE ``` De plus en utilisant des mĂ©thodes de _diffing_ (comparaison, gĂ©nĂ©ralement utilisĂ©es dans les correcteurs orthographiques ou du _fuzzy searching_/recherche floue), le vĂ©rificateur de type est capable de trouver une erreur la plus probable mĂȘme dans des cas complexes. ## Confusion entre module et module types Un des dĂ©tails surprenants d’OCaml est que beaucoup d’objets ont leur espace de noms sĂ©parĂ©, ce qui mĂšne parfois Ă  des erreurs entĂȘtantes. Par exemple : ```ocaml module type M = sig type t end type u = M.t ```> Error: Unbound module M ce message en OCaml 4.10.0 semble s’obstiner Ă  ne pas reconnaĂźtre l’existence de `M`. Le vĂ©ritable problĂšme est que `M` n’est pas un module, et donc ne dĂ©finit pas de types. Depuis la version 4.12.0, le message d’erreur reconnaĂźt qu’il s’agit d’une confusion naturelle :> Error: Unbound module M Hint: There is a module type named M, but module types are not modules ## Une explication des problĂšmes de rĂ©gularitĂ© Parfois, les messages d’erreurs sont Ă©vidents pour leurs auteurs, et totalement obscurs sans le bon contexte. C’était notamment le cas d’un des messages d’erreurs concernant les types rĂ©cursifs non-rĂ©guliers. Si l’enchaĂźnement des mots prĂ©cĂ©dents ne vous parle pas, il y avait de grandes chances que ce message d’erreur vous laisse pantois : ```ocaml type ('a,'b) x = [ `X of ('b,'a) y ] and ('a,'b) y = [ `Y of ('a,'b) x ] ```> Error: In the definition of y, type ('b, 'a) x should be ('a, 'b) x Il commet en effet trois pĂ©chĂ©s cardinaux pour un message d’erreur : il propose un correctif faux, il ne parle pas du code visible par l’utilisateur mais du rĂ©sultat d’un calcul invisible du compilateur, et il ne pointe pas vers la source de l’erreur. Ce souci est corrigĂ©, et OCaml 4.12.0 prend dĂ©sormais le temps d’expliquer le problĂšme :> Error: This recursive type is not regular. The type constructor x is defined as type ('a, 'b) x but it is used as ('b, 'a) x after the following expansion(s): ('b, 'a) y = [ `Y of ('b, 'a) x ] All uses need to match the definition for the recursive type to be regular. Le message d’erreur est long. Cependant il explique non seulement la nature du problĂšme (un type paramĂ©trĂ© est utilisĂ© de façon diffĂ©rente au sein d’un mĂȘme groupe de dĂ©finition rĂ©cursif) mais aussi comment le vĂ©rificateur de type a dĂ©couvert l’erreur. # AmĂ©liorations de l’expĂ©rience utilisateur Il y a aussi beaucoup d’amĂ©liorations de taille plus modeste qui sont plus difficiles Ă  catĂ©goriser. Parmi celles qui ont retenu mon attention sur ces deux derniĂšres versions, je peux citer : ## Statmemprof : profiler la mĂ©moire sur des programmes en production. Pour des langages Ă  glaneur de cellules (GC) comme OCaml, l’allocation et la dĂ©sallocation de mĂ©moire est un axe Ă  la fois important et assez invisible de la performance des programmes. Il peut donc ĂȘtre important de surveiller le travail du GC dans un programme pour Ă©valuer des problĂšmes de performances, ou s’assurer qu’il n’y ait pas de fuite de mĂ©moire dans un serveur tournant durant des annĂ©es. Dans les versions d’OCaml antĂ©rieures Ă  4.12, la bibliothĂšque Spacetime fournissait de tels outils de surveillance en continu de la mĂ©moire. Cependant analyser le travail du GC peut-ĂȘtre extrĂȘmement coĂ»teux aussi bien en termes de temps que d’espace. Et il Ă©tait pratiquement impossible d’utiliser Spacetime dans un environnement de production Ă  cause de ces coĂ»ts. Statmemprof est une rĂ©ponse Ă  ces problĂ©matiques : il s’agit d’un outil de profilage statistique de l’allocation et de la dĂ©sallocation de la mĂ©moire. En s’autorisant Ă  n’analyser qu’une partie des allocations et des dĂ©sallocations, il devient possible de contrĂŽler le coĂ»t de cette analyse de la mĂ©moire et de la rendre nĂ©gligeable. IntĂ©grer cette analyse dans du code en production devient alors possible. On peut mĂȘme s’autoriser Ă  ajuster le comportement du programme en fonction de sa consommation mĂ©moire actuelle. ## Des noms pour les warnings AprĂšs 25 ans d’existence, OCaml a accumulĂ© plusieurs dizaines d’avertissements (70 dans la version 4.13.0). Fort heureusement, la configuration de ces avertissements est souvent laissĂ©e soit au compilateur soit au systĂšme d’assemblage. Notamment, `dune`, le systĂšme d’assemblage de prĂ©dilection de la plupart des paquets opam, a un choix d’avertissements assez strict par dĂ©faut. Il reste nĂ©anmoins pratique de pouvoir modifier cette configuration pour un fichier ou une fonction spĂ©cifique. Par exemple, on peut activer le warning `27` pour juste la fonction `f` avec : ```ocaml let f x = () [@@warning "+27"] ``` Cependant, Ă  la lecture, il n’est pas exactement Ă©vident de se rappeler l’objet de cet avertissement `27`. Cela d’autant plus lorsque l’avertissement est utilisĂ© ponctuellement. La nouvelle mouture d’OCaml permet enfin de nommer ces avertissements : ```ocaml let f x = () [@@warning "+unused-var-strict"] ``` ## Et la Stdlib s’agrandit La bibliothĂšque standard voit arriver deux nouveaux modules liĂ©s aux threads : - `Atomic` : ce module est lĂ  pour prĂ©parer en douceur la compatibilitĂ© avec le _runtime_ multi-cƓur. - `Thread.Semaphore` : ce module offre une contrepartie au `Mutex` qui n’a pas besoin d’ĂȘtre verrouillĂ© et dĂ©verrouillĂ© dans le mĂȘme fil d’exĂ©cution. et un nouveau module de structure de donnĂ©es : - `Either` : il s’agit d’un module d’alternative gĂ©nĂ©rique (on a soit un `Left a` soit un `Right b`) qui est utile lorsque nommer explicitement les deux alternatives serait pĂ©nible. Fut un temps, la bibliothĂšque standard d’OCaml avait pour objectif de rester assez minimaliste. Ce choix a engendrĂ© la crĂ©ation d’au moins quatre bibliothĂšques Ă©tendant la bibliothĂšque standard (extlib, batteries, base, containers). Cependant depuis, OCaml 4.07 la bibliothĂšque standard s’est ouverte Ă  plus d’amĂ©liorations. NĂ©anmoins, l’évolution de la bibliothĂšque standard reste basĂ©e sur un principe de quasi-unanimitĂ©, son rythme d’évolution reste donc trĂšs mesurĂ©. ## Des piles d’appels plus expressives Lorsque qu’une fonction lĂšve une exception qui n’est pas attrapĂ©e, la pile d’appel (_backtrace_) contient dĂ©sormais des informations sur les noms des fonctions qui se sont retrouvĂ©es sur la pile d’appel. Par exemple exĂ©cuter : ```ocaml let () = let f () = let g () = raise Exit in fun () -> g () in f () () ``` nous informe que > Raised at Backtrace_example.f.g in file "backtrace_example.ml" (inlined), line 3, characters 16-26 plutĂŽt que le laconique > Raised at file "backtrace_example.ml" (inlined), line 3, characters 16-26 # Plus de types pour les utilisateurs experts Le systĂšme s’est aussi enrichi de fonctionnalitĂ©s plus orientĂ©es vers les auteurs de bibliothĂšques, et les utilisateurs experts. ## Des noms pour les types existentiels Les types existentiels sont une des fonctionnalitĂ©s nouvelles apportĂ©es par les Types de DonnĂ©es AlgĂ©briques GĂ©nĂ©ralisĂ©s (GADTs). Pour faire simple, il s’agit de types qui n’existent qu’à l’intĂ©rieur d’un constructeur. Par exemple, je peux dĂ©crire une pipeline de transformation de `'a` vers `b` en plusieurs Ă©tapes : ```ocaml type ('entree,'sortie) pipeline = | Vide: ('entree,'entree) pipeline | Etape: ('entree,'intermediaire) pipeline * ('intermediaire -> 'sortie) -> ('entree,'sortie) pipeline ``` Ici le constructeur `Etape` prend comme argument un pipeline de `entree` vers un type `intermediaire`, et une fonction de ce type `intermediaire` vers le type `sortie` et me donne en retour un pipeline de l’entrĂ©e vers la sortie. Le point intĂ©ressant avec dĂ©finition est que ce type intermĂ©diaire n’est pas un type concret connu. Il s’agit d’un type inconnu dont je sais seulement qu’il est partagĂ© par ma pipeline interne, et ma fonction de transformation. Une bonne façon de voir comment ce type se comporte est d’implĂ©menter une fonction `envoyer` qui applique toutes les Ă©tapes de la pipeline Ă  une entrĂ©e et obtient une sortie. ```ocaml let rec envoyer: type entree sortie. (entree,sortie) pipeline -> entree -> sortie = fun pipeline entree -> match pipeline with | Vide -> entree | Etape(pipeline_interne, transformation_finale) -> entree |> envoyer pipeline_interne |> transformation_finale (* [x |> f] signifie [f x] *) ``` Ici, tout ce passe bien. Mais que se passe-t-il si j’essaye d’appliquer la transformation finale avant le reste de la pipeline ? ```ocaml let rec envoyer_erronee: type entree sortie. (entree,sortie) pipeline -> entree -> sortie = fun pipeline entree -> match pipeline with | Vide -> entree | Etape(pipeline_interne, transformation_finale) -> entree |> transformation_finale |> envoyer pipeline_interne ``` J’obtiens une erreur de compilation qui se plaint que le type de `entree` n’est pas le bon :> Error: This expression has type entree but an expression was expected of type> $Etape_'intermediaire Et en effet, le code est faux parce que le type `entree` ne correspond pas au type attendu par la transformation finale. Le nom du type attendu `$Etape_'intermediaire` est cependant assez complexe. Il s’agit d’un nom automatiquement gĂ©nĂ©rĂ© pour un type existentiel Ă  partir de la dĂ©finition de type et du constructeur qui l’a introduit. Ici le nom est assez clair, mais dans des cas complexes ces noms gĂ©nĂ©rĂ©s automatiquement peuvent ĂȘtre [difficiles Ă  dĂ©chiffrer](https://ocaml.org/releases/4.12/manual/gadts.html#p:existential-names). Une des nouveautĂ©s dans 4.13.0 est qu’il est dĂ©sormais possible de nommer soi-mĂȘme les types existentiels introduits dans le filtrage de motif: ```ocaml let rec envoyer_erronee: type entree sortie. (entree,sortie) pipeline -> entree -> sortie = fun pipeline entree -> match pipeline with | Vide -> entree | Etape (type intermediaire) (pipeline_interne, transformation_finale: (entree, intermediaire) pipeline * (intermediaire -> sortie) ) -> entree |> transformation_finale |> envoyer pipeline_interne ``` Cette fois-ci, le message d’erreur utilise notre nom de type :> Error: This expression has type entree but an expression was expected of type> intermediaire Ce qui devrait rĂ©duire lĂ©gĂšrement le temps passĂ© Ă  faire compiler du code utilisant fortement les [GADT](https://en.wikipedia.org/wiki/Generalized_algebraic_data_type). Cette notation permet aussi d’obtenir facilement le type abstrait correspondant au type existentiel pour lequel il y a des applications plus Ă©laborĂ©es. ## De l’injectivitĂ© pour vos types Les bibliothĂšques vont pouvoir ajouter des points d’exclamation Ă  leurs types ```ocaml type !'a vec ``` pour indiquer que le paramĂštre `'a` est vraiment utilisĂ© dans le type et n’est pas un type fantĂŽme. Cela permet de dĂ©bloquer certains usages avancĂ©s des GADT oĂč il est vital de savoir si `int vec` et forcĂ©ment diffĂ©rent de `float vec`. Par exemple, avec cette annotation, le vĂ©rificateur de type sait qu’avec la dĂ©finition suivante : ```ocaml type _ int_or_float_vec = | Int_vec : int vec -> int vec int_or_float_vec | Float_vec: float vec -> float vec int_or_float_vec ``` lorsqu’on a une valeur de type `'a int_or_float_vec`, la variable `'a` est forcĂ©ment soit `int vec` soit `float vec`. En d’autres mots, on ne peut jamais se procurer une valeur de type `char int_or_float_vec` : ```ocaml let impossible: char int_or_float_vec -> _ = function _ -> . ``` Sans cette annotation, le vĂ©rificateur de type ne peut Ă©liminer la possibilitĂ© que le type `'a vec` ait Ă©tĂ© dĂ©fini en tant que synonyme de `char`: ```ocaml type 'a vec = char ``` Comme pour les annotations de variances, l’injectivitĂ© est automatiquement infĂ©rĂ©e pour les types non-abstraits. Ces annotations sont donc essentiellement lĂ  pour les auteurs de bibliothĂšque. # Au-delĂ  d’OCaml multi-cƓur Si l’implĂ©mentation d’OCaml multi-cƓur se rapproche lentement mais inexorablement, les plans pour le futur d’OCaml ne s’arrĂȘtent pas lĂ . En particulier, la gestion de la concurrence et du parallĂ©lisme sera Ă  terme basĂ©e sur un systĂšme d’effets. La prochaine Ă©tape de ce cĂŽtĂ© sera de concevoir et dĂ©ployer un systĂšme d’effets typĂ©s facile Ă  utiliser en pratique. Mais le dĂ©veloppement d’OCaml 5 ne se concentrera pas uniquement sur l’aspect multi-cƓur. Une des forces d’OCaml est son systĂšme de modules Ă  la fois expressif et adaptĂ© Ă  la compilation sĂ©parĂ©e. Cependant, cette puissance a un prix, et les usages avancĂ©s du systĂšme de modules peuvent ĂȘtre particuliĂšrement lourds syntaxiquement. Un des projets en cours pour OCaml 5 est d’introduire des mĂ©thodes plus lĂ©gĂšres pour dĂ©crire des fonctions paramĂ©trĂ©es par des modules, Ă  travers un systĂšme de foncteurs lĂ©gers et implicites.

AltStyle ă«ă‚ˆăŁăŠć€‰æ›ă•ă‚ŒăŸăƒšăƒŒă‚ž (->ă‚ȘăƒȘă‚žăƒŠăƒ«) /