URL: https://linuxfr.org/users/anaseto/journaux/retour-d-experience-sur-les-langages-de-programmation Title: Retour d'expérience sur les langages de programmation Authors: anaseto Date: 2020年11月13日T15:51:50+01:00 License: CC By-SA Tags: langage_de_programmation, tcl, perl, python, lisp, golang et rust Score: 42 Ces derniers temps, j'apprends moins de langages nouveaux qu'il y a quelques années. Du coup, je me suis dit que c'était une occasion de faire le tour sur l'essentiel des langages que j'ai testés. Dans ce journal, je fais un peu dans le classique du ceci ou cela m'a plu dans tel langage, telle autre chose ne m'a pas plu. Le tout est très subjectif, biaisé et reflète fortement les trucs que j'ai voulu faire avec ces langages. Mais bon, j'ai lu beaucoup d'articles de blog dans ce genre (enfin, en général sur un seul langage, ou L1 vs L2) et, même si ça n'aide pas souvent à découvrir le langage de nos rêves, ni à changer d'opinion ou à apprendre grand-chose sur un langage qu'on connait déjà, j'ai trouvé quand même ça souvent sympa à lire vite fait, même (voire surtout) quand mon ressenti est différent. # Petit tour d'expérience sur des langages ## OCaml [OCaml](https://fr.wikipedia.org/wiki/OCaml) est le premier langage que j'ai appris ! (enfin, son prédécesseur Camllight initialement, le langage qui était utilisé qu'en prépas en France) Les trucs que j'ai aimés : + Compile vers du code natif assez efficace. + Typage expressif ([types algébriques](https://fr.wikipedia.org/wiki/Type_alg%C3%A9brique_de_donn%C3%A9es)), mais pratique ([inférence de types](https://fr.wikipedia.org/wiki/Inf%C3%A9rence_de_types)) et pas trop compliqué : langage abordable. + Mélange de code fonctionnel et impératif possible et plutôt facile. + Sympa pour manipuler des structures de données arborescentes. En particulier pour écrire des analyses ou transformations d'AST. + Documentation accessible en ligne de commande. Les trucs qui me laissent dubitatif : + Des messages d'erreur qui se sont améliorés mais, le typage riche et l'inférence n'aidant pas, les erreurs ont toujours du mal à parler la langue des mortels. + Une syntaxe et un système de types pas trop compliqués, mais qui se compliquent ces dernières années : introduction des GADT (une sorte de types dépendants — en gros, des monstres surpuissants invoqués par des super héros) et les extensions de syntaxe ppx qui peuvent casser à chaque changement de version, entres autres; ça a du bon quand même. + La syntaxe : l'extension [Reason](https://reasonml.github.io/) fait plus de modifications que strictement nécessaire, mais marquer clairement la fin des *pattern matching* et autres structures de contrôle (comme en Rust), ce serait déjà bien (après, des accolades ou un `end` comme en Coq ou Ruby, c'est du détail). + Pas besoin de préciser les bibliothèques utilisées en préambule de fichier. + Un nombre ok de bibliothèques tierces. Les trucs que j'ai moins aimés : + Bibliothèque standard limitée, beaucoup de variantes de fonctions de base, mais peu au-delà (pas de compression, encodage, unicode, http). Au moins deux bibliothèques alternatives existent, mais elles résolvent surtout des soucis différents. + Exceptions, en particulier leur sur-utilisation dans la bibliothèque standard qui a conduit à l'introduction de variantes en `*_opt` renvoyant plutôt un type option, du genre `None` ou `Some x`, plutôt que `Not_found` (mais pas pour toutes les fonctions encore). + Manque de structures de contrôle impératives : pas de break, continue, return ; ça peut vite devenir gênant si on manipule beaucoup les tableaux (tableaux qui d'ailleurs gagneraient en ergonomie à être dynamiques). + Des fonctions non [récursives terminales](https://fr.wikipedia.org/wiki/R%C3%A9cursion_terminale) (donc risque de débordement de pile) dans la bibliothèque standard qui ont conduit à plus de duplication avec l'introduction de fonctions récursives terminales équivalentes. + Les bibliothèques, à moins d'être très populaires, risquent d'être mal documentées : les types des fonctions, si on a de la chance une courte description pour chacune, parfois un exemple dans le README. + Certaines bibliothèques connues font dans l'ingénierie lourde (comme le framework [ocsigen](https://ocsigen.org/home/intro.html)), pas toujours évident de trouver des alternatives plus simples et bien documentées. ## Haskell [Haskell](https://fr.wikipedia.org/wiki/Haskell) a des propriétés similaires à OCaml, à ceci près qu'il accueille avec joie la complexité. Plus amusant, mais plus frustrant aussi. Les trucs que j'ai aimés : + Compile vers du code natif assez efficace. + Typage expressif, inférence de type. + Comme OCaml, pratique pour la manipulation d'AST. + La bibliothèque [parsec](https://en.wikipedia.org/wiki/Parsec_(parser) qui permet de parser en combinant des parseurs. Des alternatives dans d'autres langages ont vu le jour, mais parsec reste plus naturel (mais pas le plus performant par contre). Les trucs qui me laissent dubitatif : + Les [monades](https://en.wikipedia.org/wiki/Monad_(functional_programming)), des abstractions qui permettent de structurer les programmes de façon générique. C'est utilisé dans parsec pour combiner naturellement des parseurs, par exemple. Les monades IO et ST permettent de faire de l'impératif de façon compliquée aussi. C'est aussi utilisé pour rendre certains tutoriels très abstraits. + Un système de types plus complexe que celui d'OCaml et qui rencontre plus tôt les limites de l'inférence. Et une pléthore d'extensions de langage optionnelles. + Des messages d'erreur pour initiés à cause du typage expressif et de l'inférence de types. + Une communauté intéressée par des concepts comme les monades, les flèches, les catégories, etc. Ça se reflète dans de nombreux tutoriels et échanges, tout comme dans les bibliothèques tierces. C'est plus dur de trouver des contenus qui font dans le pragmatique. Ce point devient positif si on est passionné par les concepts mentionnés, ou source de frustration autrement :-) + Je n'aime pas trop certains éléments de syntaxe : l'indentation significative, l'abondance d'opérateurs avec priorités et associativité variables. + Des préambules de fichier avec souvent une suite interminable d'imports de bibliothèques et un mélange d'imports avec noms qualifiés et non qualifiés. Les trucs que j'ai moins aimés : + Compilation lente. + Possible mais difficile de faire de l'impératif : manipuler des tableaux est tout sauf agréable (par exemple pour représenter la carte dans un jeu, faire de la recherche de chemins, etc.). + Il faut utiliser une bibliothèque externe pour avoir des chaînes de caractères implémentées raisonnablement. + Beaucoup de bibliothèques, mais c'est pas facile de s'y retrouver. + Beaucoup de bibliothèques font dans l'ingénierie lourde. + Beaucoup de bibliothèques ont un arbre conséquent de dépendances. + Beaucoup de bibliothèques sont mal documentées. Exemple personnel : recherche d'une bibliothèque pour gérer le xml. Première tentative, [hxt](https://hackage.haskell.org/package/hxt) : pas moyen de trouver un indice dans la doc sur comment commencer (le théoricien remarquera que ça s'inspire de la [théorie des flèches](https://fr.wikipedia.org/wiki/Morphisme), mais ça l'aidera pas forcément tant que ça non plus). Deuxième tentative, [HaXml](https://hackage.haskell.org/package/HaXml-1.25.5/docs/Text-XML-HaXml.html) : un peu moins abstrait peut-être, mais bon courage quand même. Troisième tentative, [Text-XML-Light](https://hackage.haskell.org/package/xml-1.3.14/docs/Text-XML-Light.html), le nom semble prometteur : pas d'exemples, mais ça semble en effet plus simple. Si l'on n'a pas encore capitulé, c'est le moment de chercher s'il n'y a pas un tutoriel à peu près à jour quelque part dans le wiki du langage pour une de ces bibliothèques. Ceci dit, Haskell, c'est vraiment l'occasion de découvrir des concepts théoriques en faisant des trucs concrets, du genre découvrir à l'aide d'un framework web (appelé snap si ma mémoire est bonne) que les lentilles c'est pas seulement un truc qui se mange. ## Tcl, Perl, Python, Raku Tous ces langages se ressemblent un peu : typage dynamique, bases faciles à apprendre, plus ou moins d'OO, communauté pragmatique avec des écosystèmes de packages très variés, langages pas super performants mais suffisamment dans beaucoup de cas. Du coup, je vais parler uniquement des choses marquantes qui m'ont semblé uniques à chacun. Pour Perl : + Intégration des expressions régulières dans le langage, inspirée de [Sed](https://fr.wikipedia.org/wiki/Stream_Editor) : erreurs dans la regexp à la compilation, plein de fonctionnalités sur l'Unicode. + Mode de traitement de texte inspiré de [Awk](https://fr.wikipedia.org/wiki/Awk) et adapté aux traitements rapides en ligne de commande. + Une documentation commode en ligne de commande et qui permet de démarrer vite, avec beaucoup d'exemples dans un style un peu « recettes » en synopsis. + Quelques incantations répétitives à écrire en début de chaque fichier. + Un peu plus fonctionnel (fonctions anonymes, portée lexicale des variables). + Mini typage statique partiel (scalaires vs tableaux vs tables de hachage, typos dans les noms de variables attrapées lors de la compilation). Pour Python : + Beaucoup de bibliothèques dans le domaine du calcul scientifique (numpy, etc.). + Documentation plus OO que celle de Perl, plus orientée web que ligne de commande. + [Listes en compréhension](https://fr.wikipedia.org/wiki/Liste_en_compr%C3%A9hension) (perso, j'aime pas trop, ça se démarque un peu du reste du langage). Pour [Tcl](https://fr.wikipedia.org/wiki/Tool_Command_Language) : + Syntaxe où « tout est chaîne de caractères et commandes », mais fait proprement et sans pièges, contrairement au shell. Ça permet de faire des DSLs très naturels. + Par exemple, l'intégration très sympa avec SQLite : on peut écrire `db eval {SELECT uid FROM table WHERE n <= $max AND time < $epoch}` en mettant directement les variables `$max` et `$epoch` dans la requête sans risquer d'injections SQL (c'est pas de l'interpolation en fait). Ça évite la typique redondance où il faut passer les arguments à la requête après, souvent avec le même nom. + Plus fragile aux typos que Perl ou Python. + Intégration très naturelle avec Tk : mon langage préféré pour les petits GUI couplé à SQLite. + Documentation sous forme de pages de manuel proches de celles des outils en ligne de commande : plus formelle que la documentation Perl. + Wiki communautaire plein d'exemples, mais un peu chaotique. + Écosystème plus petit que les autres : pas idéal pour faire du calcul scientifique, par exemple, et moins de choix en général (par exemple pour faire du web). + Malgré son caractère de langage généraliste et bibliothèque standard assez vaste, Tcl peut être aussi facilement utilisé comme langage d'extension d'un programme en C (à la Lua). Pour [Raku](https://fr.wikipedia.org/wiki/Raku_(langage)) (anciennement Perl 6) : + Langage généraliste à tout faire très (trop ?) ambitieux et pas effrayé par la complexité. + Langage plutôt cohérent et orthogonal, inspiré de Perl (mais aussi Ruby et d'autres), mais plus OO dans l'esprit. + Les messages d'erreur sont plutôt sympas. + Les expressions régulières sont intégrées dans un concept plus vaste de grammaires, très pratique pour écrire des parseurs. + La VM se lance un peu lentement et les modules compilent pas vite non plus. + Les expressions régulières, qui sont quand même fondamentales dans ce langage, étaient encore très mal optimisées il y a un ou deux ans, la dernière fois que j'ai testé. + L'écosystème est assez jeune encore. ## Common Lisp, Racket [Common Lisp](https://fr.wikipedia.org/wiki/Common_Lisp) et [Racket](https://fr.wikipedia.org/wiki/Racket_(langage)) sont des langages fonctionnels, par défaut au typage dynamique, ils se prêtent très bien à la manipulation de structures arborescentes et sont très prisés pour leur extensibilité à l'aide de systèmes de macros évolués. Les deux ont pas mal de bibliothèques tierces et compilent vers du code assez efficace (normalement moins que OCaml ou Haskell, mais nettement plus que Python ou Perl). Pour Racket : + Une documentation plus propre, surtout pour les bibliothèques tierces. Pour tout dire, lorsque j'ai testé, j'étais émerveillé par [scribble](https://docs.racket-lang.org/scribble/index.html), leur langage de documentation, qui est un dialecte de racket lui-même et permet de faire plein de validations sur la doc, dont le fait que les exemples compilent et renvoient le bon truc. + Plus orienté fonctionnel, mais aussi plus académique : une partie de l'objectif du langage est d'illustrer les recherches en théorie des langages extensibles. + Démarrage plus lent de la VM. Pour Common Lisp : + Macros plus simples, mais non [hygiéniques](https://en.wikipedia.org/wiki/Hygienic_macro) (ce qui est pas cool par les temps qui courent). + Un peu plus fonctionnel, en particulier la construction extrêmement flexible `loop`, ou peut-être encore mieux, la bibliothèque [iterate](https://common-lisp.net/project/iterate/) : une macro d'itération très extensible ! + Un peu le bazar pour ce qui est des bibliothèques tierces : le gestionnaire de paquets lui-même, bien que fonctionnel, est considéré bêta depuis très très longtemps. Si l'on veut juste apprendre afin de découvrir les macros pour faire des DSLs, c'est bien plus simple de faire ça avec Tcl. ## J [J](https://fr.wikipedia.org/wiki/J_(langage)) est un langage fonctionnel de manipulation vectorisée de tableaux multi-dimensionnels avec une syntaxe compacte faisant usage de primitives de haut niveau. C'est une variante moderne d'[APL](https://fr.wikipedia.org/wiki/APL_(langage)) avec une syntaxe ASCII et plus de fonctionnalités. Les trucs que j'ai aimés : + La notation compacte est sympa pour expérimenter dans l'invite de commande. + Les primitives du langage sont très génériques et flexibles. + C'est amusant et ça fait réfléchir différemment à certains problèmes : je me suis amusé par exemple avec les problèmes du project euler, la génération de cartes et algos de dijkstra, ou l'écriture d'un automate pour parser des poèmes. Les trucs que j'ai moins aimés : + Lorsqu'un algorithme ne se prête pas bien à une vectorisation, ça devient un casse-tête infernal. + J'ai beaucoup de mal à lire le code écrit par les autres. + De manière générale, j'ai l'impression que ce langage a tendance à facilement faire saturer ma mémoire cognitive de travail : un langage idéal pour quand j'ai besoin de me sentir idiot, ça marche à chaque fois. + Pour tout le code non algorithmique d'un projet, c'est aussi verbeux que n'importe quel langage et on ressent l'absence de structs/maps. Le langage est surtout utilisé en statistiques et calcul scientifique, mais je dois dire que si j'avais un besoin dans ce domaine, je chercherais plutôt du côté de Python, [R](https://fr.wikipedia.org/wiki/R_(langage_de_programmation_et_environnement_statistique)) ou [Julia](https://fr.wikipedia.org/wiki/Julia_(langage)). J'utilise J parfois comme calculatrice. En pratique je me contente souvent de la calculatrice `dc` du standard POSIX :-) ## Coq [Coq](https://coq.inria.fr/) est un assistant de preuve et un langage purement fonctionnel que j'ai pas mal utilisé pendant la thèse dans le domaine de la compilation. Je suis resté simple utilisateur, assez ignorant des théories derrière et des techniques avancées d'automatisation de preuve. Il y a eu [une dépêche](https://linuxfr.org/news/sortie-de-coq-8-5-beta-un-assistant-de-preuve-formelle) ici il y a quelques années par des gens qui connaissent bien mieux le truc (perso, j'avais juste contribué avec un exemple). Les trucs que j'ai aimés : + C'est rigolo. Sérieusement, écrire des preuves de programme, c'est un peu comme un jeu, avec des moments de victoires épiques et de défaites accablantes. + C'est un langage avec un système de types extrêmement expressif : imaginez par exemple pouvoir écrire à l'aide du système de types qu'une passe d'optimisation d'un compilateur ne change pas la sémantique d'un programme et n'introduit donc pas de bugs inattendus ! + Comme OCaml ou Haskell, le langage se prête bien à la manipulation d'AST et donc à l'écriture de compilateurs (avec des difficultés additionnelles ceci dit, comme le fait que les entiers sont représentés par un type algébrique et que Coq offre uniquement des structures de données purement fonctionnelles). Les trucs qui me laissent dubitatif : + Écrire du code propre est relativement facile, mais des preuves propres, c'est une autre histoire : il y a l'approche où on essaie d'automatiser un maximum, ce qui demande de connaître très bien le langage de tactiques (donc preuve compréhensible par moins de monde), d'avoir une machine puissante (automatisation signifie plus de travail pour Coq) et compromettre la maintenabilité (du genre preuve qui passe plus avec la version suivante de Coq); il y a l'approche où on automatise pas trop et écrit beaucoup de lemmes intermédiaires et des preuves parfois répétitives, on insiste jusqu'à ce que ça passe à force de sentiments forts : je faisais partie des utilisateurs chevronnés de cette technique de jeu. Les trucs que j'ai moins aimés : + Ça prend beaucoup de temps. Difficile de trouver des applications qui justifient cela, et ce même dans les domaines qui se prêtent assez bien à la preuve de programme (comme la compilation). + Il faut utiliser un autre langage, généralement OCaml, pour les parties non purement fonctionnelles du programme qui font de l'I/O. + C'est un langage complexe avec des messages d'erreur qui demandent une bonne expérience pour être appréhendés. + Faut pas s'attendre à trouver des contributeurs dans la nature : les programmeurs Coq se trouvent tous ou presque dans le domaine de la recherche. + Comme tout jeu, on finit par se lasser un peu à un moment et un jeu long dont on se lasse est un jeu qu'on ne finit pas (à moins d'être payé pour). + Les ressources disponibles dans la nature pour apprendre sont limitées, souvent écrites pour des gens qui font une thèse et sont intéressés par la théorie. La pratique et les astuces de preuve, faut les apprendre soi-même ou lors d'échanges avec les collègues si on a la chance d'être dans un environnement Coq. Bref, c'est peu accessible. ## Go [Go](https://fr.wikipedia.org/wiki/Go_(langage)) est un langage que j'utilise beaucoup ces derniers temps (frundis, jeux, des petits scripts), je suis plutôt satisfait. Les trucs que j'ai aimés : + Compile vers du code natif efficace. Compilation rapide, statique par défaut. + Langage : structures de contrôle impératives flexibles (for, switch, break, continue, labels de boucle), les essentiels du fonctionnel (fonctions de première classe et [clôtures lexicales](https://fr.wikipedia.org/wiki/Fermeture_(informatique))), l'essentiel de l'OO (structs, méthodes et interfaces, pas de classes), l'essentiel du typage statique (typage moyennement expressif, mais flexible au besoin et sans conversions implicites ni inférences trop génériques qui compliquent les messages d'erreur), l'essentiel des structures de données (maps et tableaux dynamiques, comme avec Perl, Python ou Ruby). + Une bibliothèque standard fournie, mais abordable et bien documentée. + Beaucoup de bibliothèques tierces bien documentées, souvent avec peu ou pas de dépendances. + Crosscompilation facile pour les programmes en pur Go (avec export en WebAssembly facile). + Programmation concurrente facile avec les channels et goroutines. + Un package, c'est tous les fichiers d'un dossier: pas besoin de faire un package différent pour éviter d'avoir trop de trucs dans un même fichier. + Documentation accessible en ligne de commande et, en général, langage pratique à utiliser dans un terminal avec plein d'outils (renommages, analyses statiques, bonne intégration vim/emacs, etc.). Les trucs qui me laissent dubitatif : + URLs pour les noms d'import de package : ça conduit à devoir modifier le code si on change l'hébergement du projet. Ceci dit, le packaging n'a pas de solution magique non plus : j'ai beau ne pas vraiment aimer cette idée, c'est souvent pratique et pas clairement pire que les alternatives sur tous les points. + Absence de types génériques ([en cours](https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md) d'être résolue, peut-être pour dans un an ou deux) : ça serait bien dans certains cas (bibliothèques génériques pour structures de données complexes ou opérations génériques sur des channels), mais ça me manque assez rarement tout compte fait (je ne ressens pas le besoin de remplacer les boucles `for` par des fonctions génériques, par exemple). + Plus verbeux qu'un langage dynamique, essentiellement du fait des signatures de fonctions (en pratique rentable dans un projet qui va au-delà du script, je trouve). Les trucs que j'ai moins aimés : + Difficile parfois de faire du pur Go (GUI, SQLite, etc.) : l'avantage de la crosscompilation facile disparaît dans ce cas. C'est pas vraiment un point négatif, mais une annulation courante de point positif. ## Rust Rust est un langage qui a pas mal de popularité en ce moment, [pas mal de trucs](https://linuxfr.org/tags/rust/public) sont passés sur linuxfr. J'ai lu un tutoriel, testé des exemples et lu de la doc, mais je n'ai jamais vraiment programmé avec, donc voici plutôt un retour d'apprentissage et d'utilisation : + Des programmes très performants, dont le génial [ripgrep](https://lib.rs/crates/ripgrep) qui remplace avantageusement grep. + Des programmes avec beaucoup de dépendances et qui mettent beaucoup de temps à compiler. + Langage d'inspirations multiples avec typage assez expressif (types somme et filtrage par motif similaires à OCaml), des [*traits*](https://en.wikipedia.org/wiki/Trait_(computer_programming)) (mais sans classes, un peu comme en Go). + Langage qui facilite l'impératif et le fonctionnel, même si l'absence de GC rend certaines pratiques de programmation fonctionnelle (comme une fonction qui renvoie une fonction) un peu alambiquées à écrire. + Un peu complexe à apprendre du fait de quelques notions assez subtiles ([*ownership*, *borrowing*](https://fr.wikipedia.org/wiki/Rust_(langage)#Possession_et_emprunt)) qui facilitent l'écriture de programmes concurrents *memory safe*, et du fait de l'ampleur du langage (macros, etc.). + Une documentation orientée web (même s'il me semble que j'avais trouvé un outil non officiel en ligne de commande). J'aimerais m'y mettre un jour, mais j'ai pas d'idée de projet personnel qui profite de l'absence de GC : un peu comme pour le C et le C++, avec la différence qu'avec ceux-ci je me suis déjà retrouvé à devoir lire voire modifier du code dans les programmes que j'utilise, et ça ne m'est pas encore arrivé avec du Rust. # Ce qu'il m'est resté de tout ça Au final, aujourd'hui, les seuls langages que j'utilise vraiment encore sont Go (pour un peu tout), Tcl (pour les GUIs et SQLite) et Perl (pour les petits scripts et [CPAN](https://fr.wikipedia.org/wiki/Comprehensive_Perl_Archive_Network)). C'est sans compter des petits bouts de Javascript (dont j'ai pas parlé, car j'ai juste écrit des petits trucs en vanilla avec la doc de mozilla, sans aller chercher quoi que ce soit dans l'écosystème), ou les modifs de code C/C++ pour compiler sous OpenBSD, et mes tentatives le plus souvent couronnées d'échec pour compiler puis lancer du Java (dernière défaite cuisante en date : le jeu Mindustry qui est passé en dépêche il y a peu). Ceci dit, même si au final on peut se dire à quoi bon avoir exploré autant de langages, j'ai bon souvenir de tout ça et ça influe probablement sur ma façon de programmer, j'espère qu'en bien :-) # Langages que j'aimerais creuser un peu un jour Un langage relativement nouveau qui m'a l'air intéressant est [txr](https://www.nongnu.org/txr/) : c'est en fait la combinaison de deux langages, un langage qui permet de capturer des motifs et parser facilement des documents, inspiré d'Awk, et un langage au style Lisp, mais différent. C'est pas un petit langage ! Dans le domaine des langages logiques, je trouve curieux [Mercury](https://fr.wikipedia.org/wiki/Mercury_(langage)), qui est un langage inspiré de [Prolog](https://fr.wikipedia.org/wiki/Prolog) pour la partie logique, et Haskell pour la partie typage. Pour ce qui est des langages concaténatifs, inspirés de [Forth](https://fr.wikipedia.org/wiki/Forth_(langage)), [Factor](https://fr.wikipedia.org/wiki/Factor) semble être une approche moderne intéressante. Ceci dit, mes quelques lectures de tutos me donnent l'impression que mon cerveau ne gère pas bien l'approche concaténative de pile dès que ça devient un peu complexe (un peu la même sensation qu'avec J, mais pas aussi marquée). J'ai vu passer assez souvent des articles sur le langage assez jeune mais plutôt actif [Zig](https://en.wikipedia.org/wiki/Zig_(programming_language)). Je me demande comment il se ressent en pratique par rapport au C voire au Rust ou C++.