- OxCaml est un ensemble d’extensions qui ajoute des fonctionnalités orientées performance à OCaml
- Il sert à la fois de compilateur de production de Jane Street et de laboratoire pour les futures fonctionnalités d’OCaml
- Il vise à étendre le contrôle des performances en mettant l’accent sur la sûreté, la simplicité d’usage et la prévisibilité
- Il propose des fonctionnalités dans divers domaines comme la concurrence sans crainte, le contrôle du layout et le contrôle des allocations
- Disponible en open source, il permet aux utilisateurs expérimentaux et aux chercheurs de tester librement et de donner leur avis
Présentation d’OxCaml
Qu’est-ce qu’OxCaml ?
- OxCaml est un ensemble d’extensions en évolution rapide pour le langage de programmation OCaml
- Il s’agit à la fois du compilateur utilisé en production par Jane Street et d’une plateforme expérimentale destinée à renforcer la programmation orientée performance dans OCaml
- L’objectif est de contribuer à long terme ces extensions à l’OCaml officiel
Principaux objectifs de conception d’OxCaml
- L’objectif est de fournir un environnement permettant de contrôler, de manière sûre, pratique et prévisible, les facteurs de performance déterminants du comportement d’un programme
- Ce contrôle n’est proposé de façon optionnelle que lorsqu’il est réellement nécessaire
- Tout est implémenté au sein de l’environnement OCaml
Approche de conception concrète
-
Sûreté : renforcer la sûreté du langage afin de garantir la productivité du programmeur et la correction du code. Les langages largement non sûrs sont difficiles à utiliser
-
Simplicité d’usage : offrir davantage de contrôle sans augmenter la complexité de la programmation, tout en conservant les avantages de l’inférence de types
-
Prévisibilité : rendre explicites au niveau du système de types les propriétés de performance essentielles, afin de faciliter le raisonnement sur les performances du code
-
Ces extensions suivent une approche pay-as-you-go, c’est-à-dire qu’elles ne s’appliquent qu’aux parties nécessaires. Autrement dit, si l’on n’utilise pas les extensions, on peut conserver telles quelles la simplicité et les patterns de l’OCaml existant
-
OxCaml est compatible avec tous les programmes OCaml et vise en interne une évolution d’OCaml. Il conserve la sûreté, la facilité d’utilisation et la productivité d’OCaml
Présentation des extensions d’OxCaml
Fearless concurrency
- Pour répondre au fait qu’une programmation concurrente correcte est très difficile, OxCaml utilise une extension du système de types pour bloquer statiquement les data races
Layouts
- Le programmeur peut spécifier explicitement le layout des données en mémoire
- Il offre aussi un accès natif aux extensions de processeur SIMD du matériel moderne
Contrôle des allocations
- Il fournit des outils pour contrôler finement les allocations mémoire, afin de réduire la charge du garbage collection (GC) et d’améliorer l’efficacité du cache ainsi que le déterminisme du programme
Améliorations de qualité de vie
-
En plus de la programmation système, il propose des fonctionnalités utiles dans le travail quotidien
- Polymorphic parameters
- Include functor
- Labeled tuples
- Immutable arrays
Utilisation et adoption d’OxCaml
-
OxCaml est publié en open source, ce qui permet aux chercheurs, utilisateurs expérimentaux et développeurs de contribuer via des tests et des retours
-
Toutefois, les extensions d’OxCaml ne garantissent ni stabilité ni rétrocompatibilité (la rétrocompatibilité avec les programmes OCaml existants reste, elle, garantie)
-
Des versions adaptées à OxCaml des outils standard d’OCaml sont fournies
- Gestion de paquets : compatible avec dune et opam
- Intégration éditeur : prise en charge du serveur LSP
- Formatage du code source et génération de documentation inclus
-
Plusieurs bibliothèques et outils publiés par Jane Street sont proposés sous deux formes
- Pour l’OCaml upstream : version sans les extensions d’OxCaml
- Dédiée à OxCaml : version exploitant les extensions
-
Certaines extensions ne peuvent pas être retirées, et les bibliothèques concernées ne sont donc utilisables que sur OxCaml. Si les extensions nécessaires sont intégrées à l’OCaml officiel, une version compatible OCaml sera également publiée
1 commentaires
Avis Hacker News
À propos de ce projet créé par l’équipe de Jane Street, je voudrais signaler qu’il y avait une discussion intéressante sur les considérations de performance lorsqu’on travaille avec OCaml dans un épisode de podcast où ils intervenaient
Les difficultés liées à l’usage d’un langage avec GC dans des environnements à latence ultra-faible restent un sujet récurrent
Par exemple, si une pause du GC survient en plein milieu d’une opération de trading haute fréquence, la situation peut devenir très problématique
Partage du lien vers le podcast
Je partage aussi avoir directement demandé à Ron Minsky sur Twitter pourquoi ils n’utilisaient pas Rust pour les applications à faible latence
Dans sa réponse, Ron reconnaissait les qualités de Rust tout en insistant sur la valeur de conserver l’ensemble du code dans un seul langage
Les types, les outils, les bibliothèques, les idiomes et la facilité de passer d’un projet à l’autre peuvent ainsi être largement mutualisés
Il mentionnait aussi qu’OCaml évolue en intégrant en interne les principaux avantages de Rust afin de permettre une adoption progressive
Parmi les inconvénients de Rust étaient cités les temps de compilation longs, la complexité du système de types et des frustrations autour de l’asynchrone/
awaitSurtout, il insistait sur le fait de vouloir un outil linguistique unique adapté à un large éventail de contextes de travail
Lien vers le tweet concerné
Il est souligné que le vrai problème n’est pas le fait qu’un langage utilise un GC, mais plutôt la tendance à mettre tous les langages à GC dans le même panier
La question vraiment importante se pose lorsqu’un langage à GC ne permet pas la manipulation explicite de la pile et des types valeur
Si l’on veut la productivité d’un langage à GC tout en gardant des options fines pour le code système, des alternatives comme Cedar, la famille Oberon, Modula-3, D, Nim, Eiffel, C#, F#, Swift et Go sont mentionnées
À propos des environnements d’exécution qui utilisent un GC, il est rappelé qu’on peut exploiter des algorithmes comme le collecteur parallèle de la JVM afin de minimiser les pauses du GC
Cela dit, cette méthode n’offre pas de garantie uniforme, ce qui impose en plus un surprovisionnement de la RAM du système
On peut aussi aller plus loin en surprovisionnant volontairement les serveurs pour permettre à certains d’entre eux de sortir temporairement du pool et d’effectuer un « GC hors ligne »
Cette approche nécessite une coopération entre le routeur de requêtes et les serveurs, et n’a de sens que si le budget permet de suffisamment faire grossir l’infrastructure
Explication du GC parallèle de la JVM
Partage d’une expérience où plusieurs systèmes ont souffert de problèmes de compaction du GC
Dans les systèmes de trading, on applique souvent une politique consistant à minimiser les allocations après le démarrage
Il existe en JS une bibliothèque nommée « Zero » qui fournit des utilitaires sans allocation
Sans avoir vérifié le lien, quelqu’un avance que dans un environnement comme le trading, avec des périodes d’ouverture et de clôture du marché, il serait peut-être possible de désactiver le GC pendant la séance puis de redémarrer après la clôture
Je voudrais souligner que la première fonctionnalité de ce fork à avoir été intégrée en amont est le tuple étiqueté
Prévu dans OCaml 5.4
Lien vers la PR upstream
Lien vers la discussion associée
Même si cette fonctionnalité peut sembler plutôt mineure, elle suscite pas mal d’enthousiasme
Je voudrais aussi ajouter comme information l’article et la vidéo présentés par l’auteur de cette fonctionnalité à ML2024
Vidéo YouTube
PDF de l’article
Comme exemple de tuple étiqueté, on peut éviter les erreurs liées à l’ordre d’une paire, mais personnellement je préfère les enregistrements anonymes de F#
Par exemple, avec
{| product = 6; sum = 5 |}, l’ordre des champs n’a pas d’importance, donc il n’y a pas ce risque d’erreurDans ce fork, les tableaux immuables ont eux aussi été fusionnés dans la 5.4, avec seulement une syntaxe légèrement différente
Il est souligné que les struct étiquetés anonymes et les enum anonymes font partie des fonctionnalités les plus désirables dans un langage de programmation
Par exemple, en Rust on peut définir à la fois des struct étiquetés et non étiquetés
Mais il est regretté qu’on ne puisse pas utiliser de struct étiqueté anonyme comme type de retour de fonction
J’ignorais que ce fork prenait en charge SIMD
S’il prend en charge les types non boxés, l’allocation explicite sur la pile et même Windows, alors OxCaml pourrait personnellement devenir tout à fait crédible à la place de F# dans des contextes grand public comme le game dev
Le support de Windows n’est pas bloqué, mais demande encore un peu de travail
Je voulais aussi souligner que c’est OxCaml qui a ajouté le support SIMD
Partage d’une astuce de configuration des variables d’environnement pour celles et ceux qui utilisent un nouveau
opam switchenv OCAMLPARAM="alert=-unsafe_multidomain,_," opam install cohttp-lwt-unixCela résout le problème où l’installation de paquets existants casse inutilement lorsque les alertes sont promues en erreurs
En désactivant cette alerte via la variable d’environnement
OCAMLPARAM, on peut éviter ces problèmes d’installationHabitué à l’excellent plugin vscode pour Golang, quelqu’un se demande s’il est prévu d’intégrer aussi l’environnement OCaml avec vscode
L’intégration avec vscode a énormément simplifié la configuration
Si OxCaml gagne en popularité, il est naturel d’imaginer que cette intégration progressera aussi
Personnellement j’utilise emacs, donc difficile d’en dire davantage, mais cela semble être une évolution logique
Je voudrais mentionner une version microscopique d’OCaml
Lien vers le projet mlite
Quelqu’un demande si l’objectif de rendre ce projet public pourrait être de faire indexer les informations par des LLM afin de les exploiter ensuite dans des modèles ouverts
Les LLM sont déjà très faibles même sur l’OCaml standard, où les données sont pourtant plus nombreuses, donc pour OxCaml où la documentation est encore plus rare, cela semble n’avoir absolument aucun sens
Dans cette optique, créer plutôt un MCP de documentation dédié serait bien plus pertinent
Comme signal, la valeur est largement insuffisante, donc cela n’a pratiquement aucun intérêt
Par exemple, même sur la complétion Gleam, les performances des LLM restent très faibles, et ils échouent même quand on leur donne des motifs clairs et des consignes explicites sur les erreurs
Pour cette raison, le signal paraît trop faible pour que la publication d’informations sur OxCaml ait cet objectif
Il est amusant de voir qu’OxCaml est une extension d’un dialecte de la famille ML lui-même dérivé d’un autre dialecte
Curiosité de voir à quoi ressemblera la prochaine étape
Je me suis déjà demandé lesquels posaient le plus problème entre ceux qui continuent d’ajouter des fonctionnalités à un langage existant et ceux qui créent directement un nouveau langage
Je fais plutôt partie des seconds, mais j’ai l’impression que les programmeurs ont une prédisposition génétique à ne jamais laisser leurs outils tranquilles
Suggestion en plaisantant : pourquoi ne pas présenter aussi F# ?
Il est confirmé que si ce projet emploie l’appellation « oxidized », c’est en raison d’objectifs fonctionnels liés à Rust — comme la fearless concurrency ou l’évitement du GC — et non parce qu’il utiliserait réellement Rust
Le nom peut donc prêter un peu à confusion
Petit point ironique : le nom Rust viendrait en réalité non pas de la rouille, mais du champignon appelé « rust »
Partage du fait que Jane Street tient depuis longtemps une série de billets de blog intitulée « Oxidizing OCaml »
Le terme apparaît aussi dans le titre de l’article « Oxidizing OCaml with Modal Memory Management », sans que le mot « oxidize » y soit explicitement défini ni cité
C’est un peu étrange, mais le nom laisse une impression assez addictive
Prévision que Rust restera plus pratique jusqu’à ce que ce projet atteigne une vraie parité fonctionnelle avec lui dans l’intégration d’un GC de traçage personnalisé, capable de gérer des structures de graphe classiques tout en visant des performances maximales
Sinon, on a surtout l’impression qu’il est maintenu parce qu’il existe déjà beaucoup de bases de code liées à OxCaml à faire vivre