Depuis toujours, le compilateur propose deux manières pour générer un programme exécutable à partir d’un code source OCaml : produire un programme binaire (dépendant de l’architecture donc) ou un byte code qui peut être réutilisé sur n’importe quelle plateforme.
Il y a dix ans, le projet js_of_ocaml apparaissait, permettant de transformer ce bytecode (que pratiquement personne n’utilise) en code JavaScript. Ce projet a ouvert une porte dans l’univers web, puisqu’il permet d’utiliser la force du langage OCaml (typage, réutilisation des bibliothèques existantes) directement dans le navigateur. Il devient possible de contrôler un formulaire saisi par l’utilisateur dans le navigateur, ou sur le serveur avec le même code : il suffit d’inclure la même bibliothèque dans la chaîne de compilation JavaScript et dans la chaîne de compilation du serveur.
Le problème du projet js_of_ocaml vient du fait qu’il se nourrit du bytecode généré par ocaml : le code JavaScript qu’il produit est un code binaire qui n’est pas destiné à être lu ou modifié. Il faut faire confiance à la chaîne de compilation qui garantit que le code qui s’exécute est bien celui correspondant au code source. De plus, étant donné que l’on passe par du bytecode, le code suit la représentation mémoire utilisée par OCaml. Une liste chaînée par exemple, est représentée en JavaScript avec la même structure qu’elle le serait en C, alors que des types natifs JavaScript auraient pu être utilisés.
Bucklescript
C’est dans ce contexte qu’apparaît en 2016 Bucklescript (EN). Ce projet, propose d’utiliser le compilateur OCaml pour générer du code JavaScript natif. Il ne s’agit plus cette fois de transformer du bytecode en code JavaScript, mais de prendre le code source, pour l’adapter directement, avec toutes les optimisations possibles.
Le code suivant (exemple tiré depuis l'outil de test en ligne (EN) :
let rec hanoi n a b c =
if n > 0
then
(hanoi (n - 1) a c b;
Js.log {j|Move disk from pole $a to pole $b|j};
hanoi (n - 1) c b a)
let _ = hanoi 4 1 2 3
est dès lors transformé en ce code JavaScript :
// Generated by BUCKLESCRIPT, PLEASE EDIT WITH CARE
'use strict';
function hanoi(_n, _a, b, _c) {
while(true) {
var c = _c;
var a = _a;
var n = _n;
if (n <= 0) {
return ;
}
hanoi(n - 1 | 0, a, c, b);
console.log("Move disk from pole " + a + " to pole " + b);
_c = a;
_a = c;
_n = n - 1 | 0;
continue ;
};
}
hanoi(4, 1, 2, 3);
exports.hanoi = hanoi;
/* Not a pure module */
Le projet, soutenu par Facebook, s’accompagne également d’une nouvelle syntaxe, Reason (EN), qui a pour but de faciliter l’accès au langage et d’éviter la difficulté d’accès liée à OCaml. Ce langage/projet prend pied dans le monde JavaScript, est compatible avec npm pour gérer les paquets, et grâce à la force du langage OCaml, permet d’unifier deux univers différents. On assiste à des projets tels que revery (EN), qui permet d’écrire des applications lourdes (avec SDL) ou web à partir d’un code unique, et comme le langage n’est qu’une couche syntaxique au langage OCaml, apporte également de la visibilité au langage.
Sauf que cette compilation au plus près des sources a un prix : celle de hacker le compilateur OCaml, et d’être dépendant d’une version donnée. Les versions d’OCaml évoluent, mais le code de bucklescript reste figé sur une version datant de 2017 (4.06), sans bénéficier des dernières avancées. De plus, la syntaxe Reason est mise en avant, OCaml étant présenté comme syntaxe alternative. Au final, il y a assez peu de porosité entre ces deux univers : le gestionnaire de paquet opam reste le gestionnaire officiel pour OCaml, esy (EN) et npm sont utilisables avec Reason, et bien que quelques passerelles existent, les deux univers coexistent l’un à côté de l’autre sans réellement fusionner.
ReScript
En 2020, Bucklescript et Reason deviennent ReScript. Derrière ce changement de nom se cache également un changement de direction : OCaml n’est plus présenté comme syntaxe alternative — même s’il est toujours utilisé dans la chaîne de compilation, le monde JavaScript seul est pleinement assumé. On peut supposer que nous sommes en train d’assister à la naissance d’un nouveau langage qui prend son envol à partir d’OCaml (comme F# l’a fait également en son temps, passant d’un simple backend .NET pour OCaml à un langage indépendant et intéressant). Même si l’on peut regretter une dispersion dans les ressources, souhaitons bonne chance à ReScript !
N. D. M. : le compilateur est sous LGPLv3 avec exception pour les liens et la documentation du langage sous MIT.
Aller plus loin
- Js_of_ocaml , manuel (15 clics)
- Test en ligne (23 clics)
- Annonce de la naissance de Bucklescript (19 clics)
- Rescript (72 clics)
# Merci!
Posté par fero14041 . Évalué à 2.
Merci pour cette dépêche, c'était exactement celle que j'espérais quand j'ai appris récemment la création de ReScript! Ne suivant que de très loin et épisodiquement le(s) projet(s), ce n'est pas évident de bien comprendre, et la dépêche m'a pas mal éclairé…
[^] # Re: Merci!
Posté par chimrod (site web personnel) . Évalué à 5.
D’abord un grand merci à aux contributrices et contributeurs qui ont participé à l’écriture, et merci également d’avoir pris le temps pour ton commentaire !
Cette dépêche est restée longtemps dans les tuyaux de la rédaction avant d’être validée, et j’ai été relancé plusieurs fois par la team qui s’inquiétait de la voir stagner… Tout d’abord par faute de temps de ma part (l’excuse facile), mais aussi parce que cette histoire est malheureusement chargée d’affect. La lecture de fils de discussions tel que Is rescript damaging Ocaml ecosystem? m’a touché et a rendu l’écriture d’une synthèse neutre vraiment difficile. Et la seule solution pour synthétiser ça et de marcher sur des œufs dans ce que l’on écrit… ce qui demande encore plus de temps au point d’en casser l’élan.
Il manque selon moi tout un pan qui aborderai la question de la réception du langage auprès des utilisateurs, mais je n’ai pas réussi à l’écrire. Pour ceux qui sont intéressé pourront trouver d’autres échanges dans A short history of ReScript (BuckleScript) (qui peut se lire comme un droit de réponse suite aux accusations) et vous faire votre propre avis !
[^] # Re: Merci!
Posté par octachron . Évalué à 1.
Félicitation pour avoir réussi à finir cette dépêche d'ailleurs. J'avoue l'avoir évitée dans l'espace de rédaction, justement à cause du surcoût d'énergie demandé par une écriture neutre.
J'espère que la situation sera plus claire dans le futur, lorsqu' OCaml sera passé en version 5, tandis que Rescript sera resté un fork d'OCaml 4.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.