Merci pour vos partages et opinions, très intéressants à lire. Énormément de réflexions intéressantes, trop longues à toutes relever. Merci aux intervenants.
Y’a un petit détail qui m’a fait tiquer plusieurs fois Helios, si tu me permets
Le principe d’un langage interprété est de faire oublier la machine.
J’ai l’impression que tu mêles plusieurs fois "langage interprété" et "langage haut-niveau".
Une partie de ce que tu exprimes à propos des performances n’est pas nécessairement lié à interprété / compilé.
Prenons l’exemple du JIT (que tu citais) (qui pourrait d’ailleurs fonctionner avec le Garbage collector, d’ailleurs, qui existe en Go, si je ne m’abuse).
Il existe des langages compilés qui tirent partir d’un JIT. Prenons l’exemple de la JVM (histoire que je sois relativement à l’aise pour expliquer ma pensée) : il pourrait apparaître logique de se dire "c’est une perte pure de ressources que de faire tourner un programme qui va chercher à optimiser mon programme".
Sauf que dans les faits, les optimisations effectuées par le JIT de la JVM lorsque mon programme s’exécute sont très largement au-delà de celles auxquelles je pourrais moi-même aboutir en écrivant du bytecode, ou pire : en écrivant le code assembleur qui est optimisé in fine.
Il y a donc quasiment 100% de chances que mon programme, écrit en Java/Scala/Kotlin/Clojure/Ruby(Jruby ayant parfois de bien meilleures perfs que l’interpréteur Ruby), soit bien mieux optimisé lorsqu’il tourne dans une JVM que la version ASM que j’aurais pu écrire. A l’échelle cela représente un gain gigantesque.
Ensuite, si on transfère le débat "interprété vs. compilé" au domaine "proche de la machine vs. idiomatique" et la notion de simplicité / complexité que vous êtes plusieurs à aborder dans vos différents messages. Là encore j’ai un avis mitigé.
Comme évoqué : "a fonctionnalités égales" bien entendu il sera préférable d’utiliser la version la moins gourmante en ressources, la mieux optimisée.
Est-ce-que cela signifie rigoureusement de choisir un langage proche de la machine comme Go ou Rust ? Je suis loin d’en être convaincu cf. mon point sur le JIT ci-dessus.
Mais quand bien même ? On dit "à fonctionnalités égales", soit, je dirais "à risque égaux". Et là, il peut y avoir un monde qui n’apparaît pas beaucoup dans vos échanges.
Admettons que je sois en train de développer un système d’optimisation de chaîne logistique. Trivialisons en disant que ce système doit gérer des conteneurs, des bateaux, avions, poids-lourds, des usines de production et d’assemblage, plus ou moins proches du lieu où le produit est consommé (j’entends par là : où il est utile).
Tous ces systèmes (la chaîne de production de l’usine, la chaîne de montage, les transports, etc.) communiquent entre eux, donc les composants informatiques assurant le transport de la donnée rentrent dans les 10% exposés par nohar : ils doivent passer à l’échelle, et être optimisés pour économiser des ressources.
On a parlé du coût humain d’entretien logiciel, parlons du coût d’un défaut logiciel maintenant, et pas en termes humains, mais bien sur le volet écologique.
Dans ce système, le moindre bug introduit par un choix technique :
- comportement inattendu en C
- erreur de modélisation de mon problème car le manque d’abstraction (système de type, par ex.) a rendu cette modélisation extrêmement difficile
- problème de conversions d’unité de mesure ou de devises
- pas d’abstraction autour des calculs flottants, ou problèmes liés à des débordements
etc.
Tous ces problèmes qui pourraient apparaître avec un langage pourtant optimal au niveau du "runtime" ont potentiellement un impact écologique désastreux (armement d’un porte-conteneur complètement vide, choix d’une usine de production en Chine pour une consommation en Europe alors qu’un producteur local faisait exactement la même chose, mais j’ai mal positionné la virgule au moment de convertir de miles en mètres, ou ai subi un débordement, que sais-je).
Que dire du système de types, aussi ? Ai-je envie de représenter le problème que je cherche à résoudre, automatiser, optimiser dans un langage proche des mathématiques ou proche de la machine (donc de l’électronique, quasiment).
Par exemple : est-ce-que ça ne vaudrait pas le coup d’implémenter mon bidule en Haskell, ou OCaml ? Pour bénéficier d’un système de type puissant qui rend mon problème plus clair. Ou "let it crash" avec Erlang/Elixir ? Est-ce-que BEAM atteindra le niveau de performances de la version que j’aurais pu écrire en C ? Est-ce-que Go m’aurait vraiment permis de modéliser tous les cas aux limites qui peuvent se produire, ou aurait-il panic
à la première occasion ?
Évidemment, on est loin du pur constat, avec lequel je suis bien entendu tout à fait d’accord, que charger 12M de scripts pour afficher un élément d’expérience utilisateur sur une page web est un véritable drame. Mais je pense qu’il faut quand même éviter de trop simplifier le problème et bien prendre en compte que s’il existe autant de solutions (langages, sgbd, etc.) c’est aussi affaire de compromis, malheureusement.
On ne travaille (ou se passionne) pas dans un monde dans lequel on aurait d’un côté une solution optimales pour tous les besoins, et de l’autre le reste des solutions sous-optimales, et à bannir. Ca serait tellement plus simple, cela dit.
EDIT parce qu’il manque une certaine forme de conclusion : On peut avoir tendance à penser que la sous-optimisation en ressources de nos "produits" (~= résultat d’un travail) logiciels sont la conséquence d’une forme de feinéantise. C’est sans doute sûrement vrai et il est important de ne pas se le cacher. Mais il ne faut pas avoir tendance à trop simplifier et s’auto-flageller gratuitement non plus. Parfois c’est affaire de compromis, malheureusement.