Limites d'interopérabilité entre Elm et JavaScript
Beaucoup de langages de programmation disposent d'une Interface d'Invocation Distante (Foreign Function Interface, ou FFI) permettant d'invoquer des fonctions d'un langage hôte. Par exemple, Scala et Clojure peuvent appeler des fonctions Java directement, Python et Haskell des fonctions C, etc.
Elm ne dispose pas de ce type d'interfaçage traditionnel avec JavaScript. Il n'est pas possible d'appeler des fonctions JavaScript arbitraires directement depuis le code Elm. C'est cette intransigeance que beaucoup d'aficionados apprécient en Elm, mais elle peut aussi vous déstabiliser ! Si vous envisagez d'exploiter Elm pour un usage commercial, nous vous invitons à étudier de façon approfondie ces exemples d'interopérabilité pour vous assurer que les flags, les ports et les custom elements sont à même de couvrir l'ensemble de vos besoins.
Pourquoi Elm a t-il opéré ce choix quand d'autres langages offrent un interfaçage plus direct ?
Compromis
Les ports sont en quelque sorte un accident dans l'histoire des langages de programmation. Il y a deux stratégies principales d'interopérabilité, mais Elm n'en applique aucune des deux :
Rétrocompatibilité totale. Par exemple, C++ est un sur-ensemble de C, et TypeScript est un sur-ensemble de JavaScript. C'est l'approche la plus permissive, qui a maintes fois prouvé son efficacité : par définition, tout le monde utilise déjà votre langage.
L'Interfaçage d'Invocation Distante (Foreign Function Interface, ou FFI) qui permet l'interfaçage direct avec les fonctions du langage hôte. Par exemple, Scala et Clojure peuvent invoquer des fonctions Java directement, comme Python et Haskell peuvent le faire en C. Encore une fois, c'est très efficace.
Ces stratégies sont très attrayantes sous le prisme de l'adoption et de la flexibilité d'usage, mais elles ne conviennent pas pour Elm pour deux raisons principales :
La perte de garanties. Un des atouts majeurs de Elm est qu'en l'adoptant, toute une catégorie de problèmes courants ne vous concernent plus. Il n'y a plus d'exceptions à intercepter, les fonctions ne peuvent plus altérer les données de façon surprenante. Nous pensons que c'est le cœur de valeur de Elm comparativement à d'autres langages alternatifs ; par contre, si nous introduisions le fait de pouvoir appeler JavaScript directement… tous ces avantages disparaîtraient instantanément. Est-ce que ce paquet lève des exceptions ? Quand ? Transformera t-il les valeurs que je lui fournis ? Dois-je surveiller cela ? Est-ce que le paquet produit des effets de bord) ? Enverra t-il des données vers un serveur tiers ? Enregistrera t-il les mots de passe de mes utilisateurs ? Un nombre important de développeurs ont été conquis par la plateforme justement pour éviter d'avoir à se poser ces questions.
Le déferlement de paquets. Il y a une grosse demande de portage direct d'APIs JavaScript en Elm. Dans les deux années précédent la première version de
elm/html
, nous sommes certains que quelqu'un aurait voulu contribuer une intégration de jQuery si c'était possible. C'est déjà arrivé dans le monde des langages fonctionnels générant du JavaScript qui ont une approche traditionnelle de l'interopérabilité. De nos observations, le déferlement de paquets est quelque chose de courant dans les langages compilant vers JavaScript. La pression n'est pas aussi forte en Python par exemple, nous supposons donc que c'est probablement lié à l'histoire et la culture unique de l'écosystème JavaScript.
Au regard de ces compromis, les ports et les custom elements sont intéressants car ils permettent d'exploiter JavaScript sans compromettre les avantages de Elm. C'est parfait ! Côté inconvénients, Elm ne peut donc pas directement s'appuyer sur l'écosystème de bibliothèques JavaScript pour bénéficier de sa visibilité et publier beaucoup de paquets rapidement. À moyen terme, c'est une bénédiction :
Les paquets sont conçus pour Elm. Au fur et à mesure que les membres de la communauté montent en compétence, expérimentent et découvrent de nouvelles façons de faire, nous voyons arriver des innovations dans le domaine de la mise en page et de la visualisation de données qui fonctionnent très bien avec l'architecture Elm et l'écosystème général. Et ce n'est qu'un début !
Le code est portable. Si un jour le compilateur arrive à générer des instructions x86 ou WebAssembly, l'écosystème Elm existant continuera de fonctionner de façon transparente, mais plus rapidement ! La délégation aux ports de la communication avec JavaScript garantit que tous les paquets sont intégralement écrits en Elm, et Elm lui-même a été conçu de sorte que d'autres compilateurs ciblant autre chose que JavaScript soient viables.
Les paquets sont mieux sécurisés. Les langages comme JavaScript ont de sérieux soucis de sécurité avec leur paquets. Les vols d'identifiants ou de clés d'API sont courants, infligeant un coût de vérification permanent des paquets publiés et utilisés. Est-ce que ce paquet ajoute un keylogger à l'objet
window
? Les paquets Elm garantissent que des familles entières de failles sont rendues tout simplement inexploitables, réduisant drastiquement les charges d'analyse et de sécurisation des projets.Les optimisations sont facilitées. Le style de code généré a évolué significativement au gré des versions par le passé. Par exemple, la version 0.19 a permis de réduire la taille des fichiers générés de façon spectaculaire en (1) générant du code mieux adapté à la minification JavaScript et (2) en utilisant des représentations de types personnalisées dépendant du niveau d'optimisation souhaité. Nous espérons que cela évoluera vers une meilleure fragmentation de code si on arrive à trouver une façon encore plus optimale de gérer l'application partielle. De plus, le compilateur, s'appuyant sur la notion de pureté, pourrait à terme transformer le code de façon encore plus agressive que d'autres compilateurs devant composer avec ces contraintes. Figer notre capacité à jouer sur ces facteurs d'optimisation rendrait l'opération tout simplement impossible.
Elm a donc choisi d'emprunter un chemin long et difficile, mais les langages sont conçus pour durer 30 ans ou plus. Ils doivent assurer un support aux équipes et entreprises pendant des décennies et, quand nous imaginons à quoi Elm ressemblera dans 20 ou 30 ans, les compromis que nous avons fait avec les ports semblent très prometteurs ! Si ce sujet vous intéresse, la conférence “What is Success?” d'Evan explore cet aspect stratégique des choses.
À nouveau, emprunter ce chemin peut sembler décourageant à certains. Il existe beaucoup d'autres langages alternatifs qui ont une approche FFI plus traditionnelle, et nous vous encourageons à les considérer si vous pensez qu'elle a plus de sens pour vous. Est-ce que leur écosystème est cohérent ? Obtenez-vous des exceptions à l'exécution plus souvent ? C'est possible, mais peut-être que la souplesse supplémentaire apportée justifiera ce choix pour vous. Nous vous encourageons sincèrement à examiner attentivement les exemples d'interopérabilité avec JavaScript pour décider si les flags, ports et custom elements sont à même de couvrir tous vos besoins. C'est particulièrement important si vous envisagez d'exploiter Elm pour un usage commercial !