article: de https://peterme.net/
Nim est-il un transpileur ?
19 octobre 2021 - Conception du langage , Nim , Programmation
C'est une question qui revient maintes et maintes fois sur le canal IRC, lorsque l'on parle aux gens en personne, et dans la section des commentaires à peu près à chaque fois que Nim a un article sur Hackernews ou l'un des plus gros sous-programmes de programmation. C'est aussi une question qui a été maintes fois répondue, à la fois par un « non » court et efficace, mais aussi sous une forme plus longue. Cet article expliquera en détail pourquoi la réponse est «non» et pourra, espérons-le, servir de référence la prochaine fois que cette question sera posée.
Qu'est-ce qu'un compilateur de toute façon?
Ceux qui posent la question « Nim est-il un transpileur ? signifie généralement "par opposition à un compilateur", donc pour comprendre pourquoi la réponse est "non", nous devons comprendre la différence entre un compilateur et un transpileur. Bien que ces mots soient parfois utilisés de manière interchangeable, il existe une distinction subtile mais importante dans leur sens. Mais avant d'entrer dans le vif du sujet, qu'est-ce qu'un compilateur exactement ? Les compilateurs existent depuis presque aussi longtemps que les ordinateurs sont utilisés. Les premiers ont commencé à apparaître au début des années 50, alors que les ordinateurs devenaient de plus en plus performants. Le travail d'un compilateur est de prendre un programme écrit dans un langage abstrait et de le convertir en quelque chose de plus concret. De nombreux compilateurs compileront à partir du langage de votre choix directement en code binaire, comme GCC, ou dans un format de bytecode VM particulier, comme le compilateur Java. D'autres compilateurs prendront un langage d'abstraction supérieure et le compileront simplement en une implémentation plus concrète dans un langage différent. Un exemple de ceci est TypeScript, qui compile son code en JavaScript, exécutant toutes les vérifications de type statique et autres avant de sortir uniquement du code JavaScript valide.
Mais je pensais qu'un transpiler venait de convertir entre les langues?
Cela semble être l'idée fausse qui amène les gens à poser la question qui intitule cet article. S'il est vrai qu'un transpileur convertit d'une langue à une autre, la distinction réside dans les niveaux d'abstraction. En compilant C en assembleur, vous utilisez essentiellement des informations dans le langage C pour prendre des décisions sur le code assembleur à générer, supprimez les informations dans le processus. Un transpiler en revanche est un outil qui convertit entre deux langues tout en gardant le même niveau d'abstraction. Une transpilation théorique parfaite est donc un processus à double sens où l'on peut faire des allers-retours entre les langues. Cependant, ce n'est généralement pas le cas en raison des changements structurels et des hypothèses nécessaires pour transpirer entre deux langues différentes. Des exemples de transpileurs incluent JSweet qui convertit de Java en TypeScript, f2c qui transpile Fortran 77 en C, ou J2ObjC qui convertit de Java en Objective-C, ou encore l'outil c2nim qui est livré avec Nim et compile de C à Nim. Les transpileurs sont généralement utilisés lorsque vous souhaitez utiliser le code d'un langage qui se trouve au même niveau d'abstraction et l'utiliser dans un langage d'abstraction identique ou supérieure. Et même cette liste utilise le terme un peu vaguement, f2c par exemple faisait partie de la chaîne pour compiler Fortran en code machine, et traduit donc les fonctionnalités Fortran en C.
Alors, qu'est-ce qui fait que Nim n'est pas un transpileur ?
Le compilateur Nim prend le code Nim et génère du code C, C++, Objective-C ou JavaScript. Cela peut ressembler étrangement à un transpiler. Surtout quand il s'agit de compiler dans les langages dactylographiés. Mais encore une fois, le point clé est le niveau d'abstraction. Nim a non seulement un système de types beaucoup plus strict que par exemple C, mais il prend également en charge la métaprogrammation la meilleure de sa catégorie. Cela signifie que le compilateur Nim ne convertira pas seulement le code Nim en code C, mais il permet au programme lui-même de générer du code Nim avec le code Nim. Cela se fait à l'aide de modèles et de macros et constitue une grande partie de ce qui rend Nim si flexible. En fait, vous pouvez écrire un transpileur dans Nim qui lit un fichier de code à partir d'une langue différente et le convertit en code Nim pendant la compilation. Donc non, Nim n'est pas simplement un transpileur, le code qu'il produit n'est pas convertible en Nim qui l'a créé et le niveau d'abstraction a considérablement baissé. En fait, le code C que Nim produit n'est même pas destiné à être lu ou compris par un humain, il est généré pour être aussi rapide que possible, et Nim fait quelques astuces astucieuses pour que le compilateur C crache du code machine plus efficace. Ces fonctionnalités placent Nim confortablement dans l'espace du compilateur.
Alors n'y a-t-il rien qui soit un vrai transpiler ?
La définition ci-dessus est assez stricte, et après l'avoir lu, beaucoup de gens se poseront cette question. Et tout dépend de la rigueur avec laquelle vous voulez être dans votre définition. Une syntaxe différente est-elle une abstraction ? Java et Objective-C sont-ils suffisamment similaires pour qu'ils ne franchissent pas les limites de l'abstraction ? La réalité de la situation est que toutes les langues ont des différences, après tout, quelle serait la raison de créer une copie exacte d'une langue ? Mais en général, le terme est le plus souvent appliqué aux outils autonomes qui prennent un projet déjà complet dans une langue et le convertissent dans une autre langue. Parfois, ces outils peuvent même ne pas effectuer la conversion à 100% avec précision ou même échouer carrément sur des parties qui ne peuvent pas être traduites avec précision. Ces outils sont souvent utilisés pour effectuer une conversion ponctuelle d'une langue vers une autre, ou simplement pour pouvoir utiliser une certaine bibliothèque dans une autre langue que celle qui a été écrite. Cependant, le terme est également utilisé dans des termes plus décontractés pour décrire, par exemple, Babel qui convertit du JavaScript de nouvelle génération en JavaScript compatible avec les navigateurs (Babel lui-même se définit comme un compilateur), ou même CoffeeScript qui est principalement une transformation syntaxique élaborée en JavaScript (et se réfère également à lui-même en tant que « compilation vers JavaScript »). Comme l'utilisateur "mst" l'a mis en discutant de cela sur IRC :
transpiler, n. : le compilateur de quelqu'un d'autre
Remarques finales
En résumé, le mot transpiler a été assez galvaudé ces derniers temps. Et tandis qu'une définition plus détendue que celle que j'ai utilisée ici peut certainement être appliquée, vous devrez l'assouplir presque jusqu'à l'absurdité afin de catégoriser Nim comme transpileur. Nim utilise C à peu près de la même manière que Rust utilise le LLVM par exemple, simplement une cible pour la compilation qui s'optimisera bien et s'exécutera sur de nombreuses cibles différentes. Après tout, se tenir sur les épaules de géants est un excellent moyen d'atteindre un long chemin sans avoir à faire beaucoup d'escalade.
Partager