Et les moutons électriques rêvent-ils ? Cette question du transpileur qui serait un type de compilateur s'est posée récemment, à la croisée de deux discussions. La première discussion était autour d'un article qui était censé suivre une approche philologique sur les langages de programmations. Sauf que l'article ne décrivait pas ce qu'était un langage. Et visiblement, l'auteur n'avait pas envie de se donner la peine de savoir ce qu'était la programmation. Dans l'approche gloubi-boulguesque du tout est tout et de la langue n'est que ce que les gens en font à l'instant t, il est ressorti néanmoins une chose qui mérite d'être examinée : ce qu'on appelle "le langage machine".
On pourrait se dire que l'homme parle à la machine, qu'il a une discussion, et donc, qu'il y a un langage derrière cet échange : le langage machine. Mais nos programmes sont tout sauf des dialogues. Il n'y a pas d'aller-retour entre l'homme et la machine : la machine ne fait qu'une et une seule chose, dérouler ses instructions. Quelles instructions ? Uniquement celles qui sont gravées dans son silicone (à un microcode près) : il n'y a pas de compréhension, pas d'interprétation, pas d'adaptation, juste un chemin électronique. Peut-on encore parler de langage si son destinataire principal ne l'entend pas de cette oreille ? Admettons le un instant, même si on est plus près d'un cylindre de boîte à musique qu'autre chose.
Puis une deuxième discussion arrive, sans lien avec la première, avec la réécriture du transpileur TypeScript en Go, et, suite à échange, quelqu'un dit "un transpileur c'est un type de compilateur, même Wikipedia est d'accord". Wikipedia qui est bien souvent de l'IA humaine, c'est-à-dire un contenu extrêmement plausible, mais trop souvent le fossé entre la source d'information et la page est difficile à franchir. Et effectivement, la page de Wikipedia en langue française est d'accord avec ce point de vue. Mais pas exactement la page correspondante en langue anglaise : si le mot "compilateur" apparaît bien dans le titre, il est absent de la définition, et son utilisation dans le reste de l'article est très "libérale" comme on dit chez l'oncle Sam.
Il faut savoir que pour les compilateurs, la ligne scripturale de référence est due à Alfred Aho et Jeffrey Ullman. Dans leur premier livre, Principles of Compiler Design (1977), on peut lire dans l'introduction :
The emphasis is on solving the problems universally encountered in designing a compiler, regardless of the source language or the target machine.
L'accent est mis sur la résolution des problèmes universellement rencontrés dans la conception d'un compilateur, quel que soit le langage source ou la machine cible.
On ne parle pas ici de langage cible, mais de machine cible. Allons en 1986 dans le fils spirituel de ce livre, à savoir Compilers. Principles, Techniques and Tools, des mêmes auteurs ainsi que Ravi Sethi. A peu près au même endroit dans l'introduction, on peut y lire ceci.
The emphasis is on solving the problems universally encountered in designing a language translator, regardless of the source or target machine.
L'accent est mis sur la résolution des problèmes universellement rencontrés dans la conception d'un traducteur de langue, quelle que soit la machine source ou cible.
La notion de langue se retrouve désormais lié à la notion de machine, et surtout, on ne parle plus de compilateur, mais de traducteur. Le reste de l'introduction reprend le mot compilateur tel quel, sans revenir sur le changement de vocabulaire. On voit néanmoins poindre un chapitre qui parle de "langage intermédiaire", mais au final, le sommaire nous dit qu'on génère du code, pas un texte dans une langue, ni un discours, du code. On n'est pas dans le vocabulaire du langage. On nous dit néanmoins que le compilateur ne serait qu'un traducteur de langages, donc, il doit y avoir langages pour travailler, n'est-ce pas ?
Tentons la fuite en avant, avec cet article de 1953 de Grace Hopper intitulé "Compiling Routines". Ce que j'aime avec ces articles, comme ceux de Barbara Liskov d'ailleurs, c'est qu'à peu près personne ne les lisent, mais tout le monde les louent. On parle de compilation de routines, pas vraiment encore d'API mais ça ne tardera plus, et le début de l'article se concentre sur compilation versus interprétation. Mais ce n'est pas exactement ce à quoi on pense aujourd'hui. Le mode interprété est celui où on saute de la routine principale à la sous-routine "interprétée", avec un transfert de contexte d'entrée explicite, et une récupération de la valeur calculée explicite elle aussi. Dans le mode compilé, le code de la sous-routine a été intégré, ou compilé, à l'intérieur de la routine principale, ce qui fait que toutes les positions mémoires pour les sauts ont du être recalculées.
En 1953, le travail du compilateur était donc de compiler, c'est-à-dire de rassembler des éléments divers et d'en faire un tout qui tient debout. Et pour répondre à la question du titre : si le transpileur fabrique un tout à partir de choses diverses, alors oui, on peut dire que c'est un compilateur. Et croyez-moi, arriver à faire un truc qui tient debout avec du TypeScript et du JavaScript, ça n'est pas une mince affaire.