- Un nouveau backend prenant en charge la génération de code C++ a été proposé pour le compilateur OCaml, afin de compenser les limites du backend existant basé sur C
- Le code converti est écrit dans un style fonctionnel pur, sans état mutable ni utilisation de la bibliothèque standard, avec une réimplémentation partielle du module
List
- L’exécution nécessite un compilateur C++ (
g++), avec prise en charge d’options pour lever la limite de profondeur des templates ou transmettre des arguments
- Les performances varient selon le compilateur ; l’application d’un algorithme de crible amélioré basé sur une file de priorité améliore la vitesse et l’efficacité mémoire
- La communauté y voit une expérience combinant langage fonctionnel et métaprogrammation par templates, avec une possible extension à Rust également évoquée
Proposition d’ajout d’un backend C++
- Un patch proposant d’ajouter un backend C++ au compilateur OCaml (
ocamlc) a été soumis
- Il s’agit d’une amélioration du backend C non incrémental déjà utilisé dans le runtime et la FFI
- La commande
ocamlc -incr-c primes.ml permet de convertir du code OCaml en C++
- Le code C++ généré est écrit dans un style fonctionnel pur et ne prend pas en charge l’état mutable
- De ce fait, la bibliothèque standard ne peut pas être utilisée ; dans l’exemple, une partie du module
List est réimplémentée en style purement fonctionnel
- La sortie est représentée sous forme de structure imbriquée
Cons<hd, tl>, avec une structure distincte pour éviter le conflit avec l’opérateur :: de C++
- L’exécution nécessite un compilateur C++ (
g++), et l’option -Dlimit=100 permet de transmettre des arguments
- Le résultat d’exécution s’affiche sous la forme de messages d’erreur du compilateur
- Pour les calculs de grande taille, l’option
-ftemplate-depth=999999 permet de lever la limite de profondeur des templates
- Les performances varient selon le compilateur
g++ met environ 30 secondes et utilise 11GiB de mémoire pour calculer les nombres premiers jusqu’à 10000
clang++ affiche un avertissement en moins d’une seconde puis se termine par une erreur de segmentation
- L’application de l’algorithme de crible de O’Neill basé sur une file de priorité améliore les résultats à 8 secondes et 3.1GiB
- Une prise en charge future de Rust est évoquée comme piste d’extension
- Il est mentionné que Rust pourrait exécuter des programmes OCaml une fois le
impl specialization partiel finalisé
Réactions et discussions de la communauté
-
Tests de fonctionnalité et retours
redianthus demande si les types de données récursifs non uniformes sont pris en charge
stedolan corrige une erreur due à l’absence d’implémentation de %predint et confirme que ce type fonctionne correctement
-
Humour et réactions
avsm plaisante : « On avait besoin de C--, et voilà du C++, faisons un compromis avec C# »
stedolan répond : « L’an prochain, j’essaierai les nombres complexes ℂ »
- De nombreuses réactions en émojis comme 😂, ❤️ et 🚀 confirment l’accueil positif de la communauté
-
Propositions techniques
AdelKS propose une alternative utilisant l’évaluation constexpr plutôt que les templates
- Il partage un exemple de code qui calcule les nombres premiers à la compilation et les intègre directement dans le binaire
LoganDark répond avec humour : « Mais là, on perd tout le plaisir pur de la chose », pour expliquer l’usage des templates
-
Discussions supplémentaires
redianthus affirme que « C++ est désormais devenu un véritable langage fonctionnel »
- Il souligne qu’il est possible d’implémenter en C++ les structures de données purement fonctionnelles d’OCaml
dzmitry-lahoda mentionne qu’il existe déjà un projet permettant d’exécuter OCaml sur Rust (contextgeneric/cgp)
Exemples de performances et d’exécution
- Exemple de base : programme de calcul des nombres premiers
ocamlc -incr-c primes.ml → génération de primes.cpp
- exécution de
g++ -Dlimit=100 primes.cpp pour afficher la liste des nombres premiers
-
Configuration haute performance
g++ -ftemplate-depth=999999 -Dlimit=10000 primes.cpp
- environ 30 secondes, 11GiB de mémoire utilisés
-
Avec l’algorithme amélioré
- performances améliorées à 8 secondes et 3.1GiB
Conclusion
- Cette PR est une expérience de nouveau backend convertissant OCaml en C++,
montrant la possibilité de combiner langage fonctionnel et métaprogrammation par templates
- La communauté y voit un exemple mêlant humour technique et expérimentation créative, et y réagit activement
- La possibilité d’une extension vers d’autres langages, comme Rust, est également évoquée
1 commentaires
Commentaires sur Hacker News
C’est vraiment excellent. Je voudrais donner un conseil quand on écrit du code C++ destiné à tourner longtemps
Étrangement, l’interpréteur C++ n’a absolument aucune tail call optimization
Donc la plupart du code C++ idiomatique implémente directement des fonctions comme
reverse,map,range,filterpour éviter de faire exploser la pileSi c’est implémenté de cette façon, ce sera bien plus facile pour la personne qui fera la maintenance. Mieux vaut utiliser une approche portable plutôt que de dépendre d’un flag en ligne de commande
La phrase « avec ce genre de structures de données avancées, g++ calcule les nombres premiers jusqu’à 10000 en seulement 8 secondes, en n’utilisant que 3,1 GiB de mémoire » m’a fait rire
Enfin, je vais pouvoir calculer des nombres premiers sur mon portable
J’ai vraiment adhéré au passage disant que « ce code est traduit en un C++ idiomatique et lisible »
En tant qu’amateur de C++, je pense que c’est vraiment du code C++ agréable à lire
typedef I<((I<((n::val (p::val))>::val) != (I<0>::val))> res;relèvent vraiment de la sorcellerie de templatesC’est la première fois que je vois une condition mise à l’intérieur d’une définition de type en C++
En y regardant de plus près, j’ai compris que ce n’était pas du vrai code, mais une partie de la logique d’évaluation des templates
Autrement dit, une partie de la logique du compilateur d’un langage de haut niveau a été déportée vers le moteur de templates
Cette approche peut être plus efficace que de passer davantage de temps sur le parseur
Du coup, je me demande maintenant si je ne devrais pas utiliser C++ comme cible de lowering pour le framework de compilateur elevate que je suis en train de développer
En lisant la phrase « C++ is a purely functional language », j’ai d’abord cru à une coquille, ce qui m’a fait hausser les sourcils
Mais quand j’ai compris que ce n’en était pas une, j’ai trouvé ça encore plus intéressant. Le reste du contenu était excellent lui aussi
Cet article a illuminé ma journée. Merci
Stephen Dolan ne déçoit décidément jamais. Il arrive à surprendre à chaque fois
En lisant le passage « C++ est un langage purement fonctionnel et ne prend pas en charge l’état mutable. Pour exécuter un programme C++, il faut un interpréteur C++ »
j’ai vraiment cru pendant un instant à une blague du 1er avril. Alors qu’on était déjà après avril