Bruno:
Faire un programme, c'est un peu comme faire une recette. Tu prends des ingrédients, tes entrées, tu suis des étapes et tu serres le plat, tes sorties. Mais imagine un monde où à chaque fois qu'un plat manque un peu de sel, tu dois refaire entièrement toute ta recette. Éplucher les patates, refaire cuire l'eau, ressaisir les légumes, bref, tu dois tout refaire de A à Z. Et oui, même si t'avais juste oublié une petite pincée de sel. Mais alors, comment éviter de tout refaire quand une simple entrée change ? Est-ce qu'un langage peut savoir précisément quoi remettre au feu et quoi garder au frigo ? Et surtout, comment on compile un plat sans faire exploser le micro-ondes ? Pour répondre à ces questions de grand chef, je ne reçois pas Philippe Etchebest, mais il s'y connaît en cache bien salé. Julien, bonjour.
Julien:
Bonjour.
Bruno:
Alors Julien, est-ce que tu peux te présenter pour les quelques personnes qui ne te connaîtraient peut-être pas ?
Julien:
Oui, tout à fait. Alors Julien Valaguay, moi j'ai un background essentiellement langage. J'ai passé près de 10 ans à Facebook et là, je suis CEO d'une boîte qui s'appelle Skip Labs. Alors, mon fait d'arme le plus connu, ça va être Hack, je pense, auprès de vos auditeurs. Donc, c'est une version, c'est un dialecte graduellement typé de PHP qui est très utilisé chez Facebook, aussi chez Slack, moins dans la communauté open source. Mais voilà. Et après, j'ai fait Skip. Donc, Skip, c'est un langage de programmation réactive. Et donc là, maintenant, je suis parti faire une startup autour de cette techno, une startup qui s'appelle Skip Labs, qui est basée aux US, mais on est full remote. Donc, on a des gens un peu partout, notamment à Paris. Et voilà, c'est une belle aventure. Donc là, c'est une startup où vraiment, on est programmation réactive. On fait un framework de programmation réactive. Et donc le réactif ça fait 10-15 ans que je suis dessus donc effectivement le chef a vu passer des plats.
Bruno:
Est-ce que justement tu peux nous expliquer un peu ce que c'est que cette fameuse programmation réactive.
Julien:
? Déjà le mot est un peu, le terme est un peu galvaudé parce que ça dépend vraiment à qui tu parles t'as des gens qui vont...
Bruno:
On est d'accord que ça n'a rien à voir avec React ?
Julien:
Alors ça a un peu à voir avec React disons qu'il y a je vais dire deux grandes écoles t'as l'école. Streaming donc là par exemple les Reactive Extension le truc de Microsoft donc là c'est vraiment des gens qui font des librairies de streaming qui composent des streams et ils appellent ça Reactive bon très bien c'est une communauté, mais eux dans leur dans leur manière de travailler il n'y a pas du tout d'incrémentalité c'est juste j'ai des streams ils produisent des choses et puis je vais les composer et puis ça va faire d'autres streams bon, Donc ça, il y a des gens qui appellent ça réactif. Très bien, c'est une communauté. Et tu as une autre communauté... Qui, eux, font du réactif. Mais alors, eux, c'est plutôt dans le sens... Imagine un peu comme quelque chose qui fonctionne comme un tableau Excel. C'est-à-dire que tu as une feuille de calcul Excel, tu changes une des cellules, puis pouf, il y a tout qui se met à jour. Donc ça, c'est les réactifs, une deuxième classe de réactifs. Donc ça, ça va être React, par exemple. React, c'est tout à fait ça. C'est je change un petit bout et je ne vais recalculer que ce qu'il faut. Mais il y a aussi, par exemple, Elm, le langage. Enfin, il y a beaucoup de choses comme ça. Moi, pour moi, le réactif, c'est plutôt la classe B. C'est-à-dire, le streaming, je ne comprends pas pourquoi on appelle ça réactif. Pour moi, c'est du streaming. Après, si tu prends du streaming et qu'à l'intérieur, tu fais des choses incrémentales, ça, pour moi, c'est du réactif. Mais le terme réactif pour des choses qui sont vraiment du pur streaming. Je trouve ça bizarre bon maintenant qu'est-ce que c'est ? parce que là j'ai expliqué qu'il y avait deux communautés finalement c'est pas très très compliqué, t'as un programme il y a des entrées, et ce que t'aimerais, alors les entrées des fois elles changent tout le temps, c'est un stream de changement peut-être, ou alors ça peut être un fichier, un truc qui change de temps en temps c'est pas très important, mais ce qui est important c'est t'as des entrées qui arrivent et toi ce que t'aimerais c'est recalculer ton programme pas depuis le début. Donc, t'aimerais mettre à jour, entre guillemets, l'état du programme dans lequel il était avant, au lieu, tu vois, de tout recalculer à chaque fois. Alors, évidemment, il y a plein de choses dont il faut tenir compte. La première, c'est que si tu te fiches des performances, le réactif n'a aucun intérêt. Si tu te fiches des performances, à chaque fois que tu as une entrée qui change, tu recalcules tout, il n'y a pas de problème. Et franchement, si you can get away with it, comme ils disent aux US, franchement, fais-le, quoi. Parce que tu auras beaucoup moins de problèmes, ce sera beaucoup plus simple à débuguer, tout va être simple. Donc, le réactif, ça va devenir intéressant quand tu as beaucoup d'entrées et tu as besoin de mettre à jour l'état d'un système. Ce système, il peut être arbitrairement complexe, il peut être distribué, il peut être tout ce que tu veux. Et que cette mise à jour, t'as pas envie t'as envie qu'elle se fasse de manière automatique donc. Il y a de mauvaises manières d'écrire un système réactif. La mauvaise manière, c'est à la bite et au couteau. Et je pense que tous les gens qui nous écoutent l'ont fait à un moment ou à un autre. Ça s'appelle l'invalidation de cash à la main. Et ça, c'est pas drôle. C'est-à-dire que je te donne un changement et je te dis, bon, ben voilà, maintenant, il va falloir que t'ailles mettre à jour l'état de tout ton système. Si en plus, c'est distribué, là, tu vas vraiment te faire des bons nœuds au cerveau. Et donc l'idée du réactif c'est de dire non mais attends en fait c'est une idée qui est très similaire avec React et donc je vais prendre l'exemple de React parce que je pense que les gens connaissent bien React l'idée du réactif c'est de dire non mais attends quand j'ai un système même complexe qui a plusieurs machines qui tournent etc. Sémantiquement moi je sais ce qu'il doit faire dans un état T c'est à dire que ce que dit React si on revenait dans les années 90. On faisait des GUI. À chaque fois, on cliquait sur un truc et puis, pof, on lançait un thread ou on lançait une callback et puis, avec tes petits doigts boudinés, t'allais mettre à jour l'état de la GUI. Et c'était l'enfer. Pourquoi ? Parce que tu cliquais sur un truc. Tu ratais la moitié des mises à jour, ton app se retrouvait dans un état que personne ne comprend, et puis c'est indébuggable, et voilà. Et donc, React arrive et dit, non mais attends. Non, en fait, ce qu'on va faire, c'est que tu vas dans ta tête imaginer que le temps s'arrête. Donc toi, tu fais comme si personne ne cliquait sur rien, personne ne touchait à rien. L'état ne change pas. Et tu vas m'écrire la logique de rendering avec un état qui ne change pas. Et une fois que tu as fait ça, moi, en tant que framework, c'est super facile de dériver un système qui va changer automatiquement pour toi. C'est-à-dire que quand tu me dis que quand tu es dans telle vue, tu veux voir ça à l'écran et quand tu es dans telle vue, tu veux voir ça à l'écran, s'il y a un clic qui va changer de vue, dérivez la logique qui va faire ce qu'il faut pour mettre... On sait faire. Et donc, la programmation réactive, ça consiste à faire ça. Ça consiste à dire, vos systèmes réactifs, ne les écrivez pas à la bite et au couteau en allant mettre à jour des caches à la main. Ça va être faux, ça va être horrible. mais plutôt écrivez comme si le programme, ne changeait pas d'état comme si le temps était arrêté si vous voulez et ensuite vous mettez ça vous pluguez ça dans un framework créatif qui lui va en faire un système qui va se mettre à jour. J'ai défini ce qu'était réactif, ce que j'appellerais programmation réactive. Pas tous les systèmes réactifs ont été programmés avec de la programmation réactive. Maintenant, peut-être la troisième chose qu'on peut faire, c'est donner quelques exemples. Effectivement, là, c'est très abstrait. Je vais donner trois exemples. Le premier, c'est, imaginons que tu es en ligne de commande et tu as un script et ce script, tu le lances tout le temps. Alors, typiquement, c'est le compilot. Mais il y en a d'autres, des scripts qu'on n'arrête pas de lancer en boucle. Et d'un run à l'autre, il n'y a pas beaucoup de choses qui ont changé. C'est-à-dire que toi, tu as fait un petit changement. Par exemple, tu étais en train de faire de la code gen. La plupart de tes types n'ont pas changé. Donc, tu génères normalement à peu de choses près le même code. Sauf que, bon, malheureusement, ton algo de génération de code, il met s'il plombe et tu te le tapes à chaque fois. Bon. Eh bien, ça, c'est un bon candidat pour la programmation réactive, où tu vas pouvoir dire, ben non, en fait, ce que je vais faire, c'est que je vais écrire mon système de manière réactive, il va traquer les dépendances, il va faire tout ce qui va bien, et donc, quand il y a quelque chose qui change, moi, j'ai tous mes caches qui sont encore là, donc je sais ce qu'il va falloir que je mette à jour. Donc ça, c'est un...
Bruno:
Mais du coup, c'est ton compilateur que t'écris de manière réactive ou c'est ton programme que tu compiles qui est décrit de manière réactive ?
Julien:
C'est ton compilateur que t'écris de manière réactive. Donc ça, c'est un premier exemple, c'est compilateur ou outil de ligne de commande ou ce que tu veux donc ça c'est un très bon très bon exemple pour de la programmation réactive, là c'est plutôt l'aspect incrémental c'est à dire qu'il n'y a pas trop de stream de mise à jour ou ce genre de choses c'est vraiment tu relances tu n'as pas envie de te recalculer quoi, Un deuxième exemple, c'est... Prenons un exemple pour les codeurs PHP. Donc, imaginons, tu as un site PHP et puis tu te rends compte que ta landing page, tu bouffes quand même pas mal de CPU. Tu arrives sur la landing page et puis une seconde, deux secondes, tu parles avec plein de process, de microservices, de tout ce que tu veux et ça te coûte un bras, une jambe. et surtout la latence pour les gens qui arrivent sur ton site n'est pas bonne. Et donc, tu te dis, ce que je vais faire, c'est que je vais pré-calculer la landing page pour chacun de mes utilisateurs. Je vais garder le résultat sous forme d'une page statique et puis, comme ça, quand ils arrivent, je leur serre la page statique et puis tout va bien. Évidemment, si elle ne change vraiment jamais ta landing page, il n'y a vraiment rien de dynamique. Tu la génères une fois et il n'y a pas de problème. Mais ce n'est pas comme ça que ça va se passer. La manière dont ça va se passer, c'est que t'as la landing page pour la générer, t'es allé regarder dans une base de données, t'es allé parler à des services, et ces choses-là, elles ont changé. Et donc, si tu n'as pas écrit ça de manière... Le machin qui génère les pages, tu ne l'as pas écrit de manière réactive, l'enfer, ça va être les mises à jour. C'est-à-dire que soit tu dis que c'est un cache très agressif ou avec un time to leave très court où la page, elle est générée, mais toutes les 10 minutes, elle est victe et puis bon, ça sert à rien parce qu'en gros la page elle sera évicte tout le temps, soit tu dis bah non la page je vais la garder un moment comme ça quand il y a quelqu'un qui arrive elle est pré-calculée elle est toujours bonne et là tu vas te gratter la tête en te disant merde comment je mets à jour ce truc, et donc là la programmation réactive ce que ça va faire ça va traquer la base de données ça va traquer tous les trucs qui vont bien et quand il y a un changement dans la base de données ça va pas comme un bourrin tout recalculer ça va juste recalculer tu vois la page qui va bien, Ça, c'est un deuxième exemple. Troisième exemple, ça va être pour, par exemple, faire du distribué. Donc, ça, c'est un truc que tu vas avoir souvent quand tu fais une app. C'est que tu as des bouts de ton app. Tu as besoin qu'il soit tout le temps à jour côté client. Notamment quand tu veux réduire la latence ou aussi quand c'est un dashboard, par exemple, que tu veux voir, tu es dans un jeu vidéo, tu veux voir un dashboard de quelque chose ou tu veux réduire une latence. T'as une donnée particulière qui est sans arrêt utilisée côté client et t'as vraiment besoin de la maintenir côté client. Alors, t'as le cas simple. Le cas simple, c'est quand ta donnée, c'est de la pure data. Si c'est de la pure data, c'est très simple. Tu vas dans ta base de données, tu vois qui écrit sur cette data et quand ils écrivent, t'envoies un ping côté client et tu mets le truc à jour. Mais souvent, ça ne va pas se passer comme ça. Souvent, ce qui va se passer, c'est ce qui arrive dans ton client, c'est le résultat d'un calcul potentiellement complexe qui a besoin de plusieurs tables, qui a besoin de plusieurs bases de données, qui a besoin de plusieurs trucs. Et donc là, pareil, programmation réactive, si tu le fais de manière réactive, tu vas avoir un machin qui va produire un objet réactif. Cet objet, on va l'envoyer sur ton client et ensuite, il va être maintenu à jour over the wire. Donc c'est à dire que quand et ça ça peut marcher sur plus d'une machine c'est à dire que tu peux avoir tout un système de microservices, où en fait c'est des microservices réactifs et quand même s'il se passe quelque chose de très très très profond dans la stack qui change ça se propage ça se back propage à l'envers si tu veux et ça va mettre à jour que ce qu'il faut, donc ça c'est un troisième exemple où c'est le genre de système, je dois écrire à la main je te souhaite bien du courage.
Bruno:
Alors merci pour ces trois exemples qui sont effectivement super clairs, ça permet de bien comprendre un peu dans quel contexte ce genre de programmation est utile, tu donnes du coup effectivement l'exemple de React qui a fait le choix de mettre à disposition, ce type de paradigme on va dire sous forme d'un framework ou d'une librairie je sais qu'il y a un débat sur ce que React est d'un framework ou d'une librairie, on rentrera pas là-dedans mais donc de mettre ça à disposition sous forme d'un ensemble d'outils pour que les gens puissent l'utiliser au final sans trop savoir que c'est comme ça que ça fonctionne derrière, toi t'as essayé d'en faire un langage complètement en sachant que t'avais déjà fait un autre langage avant, pourquoi à quel moment t'as qu'est-ce qui t'a fait dire que il y avait besoin d'en faire un langage complet et pas uniquement une librairie ou un framework disponible pour, du JS ou du PHP ou je ne sais quoi.
Julien:
Ah ça va être une réponse longue et compliquée.
Bruno:
C'est bon.
Julien:
On a le temps euh, Alors, comme je le disais au début, dans le réactif, ce qui va être le nerf de la guerre, c'est les perfs. C'est-à-dire que quand j'ai un... Alors, encore une fois, comme je le disais tout à l'heure, si vraiment tu veux faire du réactif bête et méchant, c'est très simple, tu recalcules tout depuis le début et puis ça marche à tous les coups. Maintenant, il y a une manière de faire du réactif qui va fonctionner avec n'importe quel langage et dans lequel tu vas avoir des perfs moins sympas mais aussi, tu vas avoir moins d'opportunités d'incrémentaliser les choses c'est quand la question à un million de dollars c'est pour résumer quand tu fais du réactif, c'est pas de la magie noire il y a des caches de partout et en gros ce que tu vas devoir faire c'est traquer ces caches, et mettre à jour ce qu'il faut quand il y a quelque chose qui change.
Bruno:
Définir des règles de mise à jour en fonction de.
Julien:
Alors tu vas avoir deux challenges le premier c'est traquer les effets de ton langage. Donc, toi, le codeur, il écrit de la logique. Si cette logique a des effets de bord, c'est très compliqué pour toi parce que toi, ce que tu veux, c'est vraiment capturer tout le calcul dans ton cache. Donc, si, en même temps, ta logique fait autre chose, va modifier, j'en sais rien, un fichier ou un truc comme ça, bon, ça, c'est quelque chose que tu n'auras pas capturé dans ton cash. Mais ce qui est encore plus important que tout ça, c'est la question à un million de dollars, c'est quand tu lis quelque chose du cash, est-ce que tu es prêt à payer une copie, oui ou non ? Si la réponse est oui, alors ton framework de programmation réactive, tu l'as torché en deux semaines avec un stagiaire. Il n'y a pas de souci. Ce n'est pas très compliqué. Ça consiste à traquer des dépendances. Bon, c'est pas le bout du monde. Ces réponses sont non. Alors là, tu rentres dans une... Alors, si tu dis non et que tu dis, bon, maintenant, quand je te donne un élément du cache, je vais te donner juste un pointeur. Et donc là, ce n'est pas du tout mutable. Et si tu as la garantie statique que c'est immutable, alors ton runtime et ton compilo vont pouvoir commencer à faire beaucoup de choses très intéressantes. Et notamment en termes de latence. C'est-à-dire que, alors, pourquoi j'ai fait un langage ? D'abord, j'avais essayé de le faire au-dessus d'OCaml. Donc moi, je connais bien OCaml, comme tous les language geeks, je pense que tu as une phase ML dans ta vie, si tu as fait un peu de typage. Moi, j'avais fait beaucoup de Caml, donc je me suis dit, je vais essayer de le faire au-dessus de Caml. Et en fait, ça s'est mal passé, parce que le problème, ce n'est pas que ça s'est mal passé, c'est que je me suis retrouvé avec quelque chose qui était juste incompatible. C'est-à-dire que ton problème, il est simple. Ce que tu veux, c'est maîtriser ce qui est mutable et ce qui n'est pas mutable pour savoir ce que tu vas pouvoir mettre dans un cache ou ce que tu vas pouvoir prendre d'un cache très efficacement sans payer de copie. La définition d'immutable dans ce contexte-là n'a rien à voir avec ce que font les autres langages de programmation. Donc, quand tu es en C++, quand il y a écrit const, const, c'est très très faible. C'est-à-dire que ça dit que la fonction que tu es en train d'exécuter ne modifie pas ce truc-là. Quand on dit immutable pour prendre l'objet et le mettre dans un cache, c'est une notion d'immutabilité qui est beaucoup plus forte. Déjà, il faut que la fermeture transitive de toutes les dépendances soit immutable. Il faut que personne n'ait de référence mutable avant ni après. Donc, c'est vraiment une fonction de la valeur que tu veux. C'est pas trop une fonction de la fonction. C'est pas un... Donc, t'as une notion d'immutabilité qui est très complexe, qui est très... Alors, complexe, c'est pas le terme.
Bruno:
Contraignante.
Julien:
Qui est très contraignante, voilà. Et t'as des systèmes de type qui sont pas du tout à jour pour gérer ce type d'immutabilité-là. Alors, tu te dis, c'est facile, moi, je vais prendre Java, je vais prendre Kamel, et puis je vais rajouter mes contraintes d'immutabilité dessus. Alors, faisons-le ensemble. On prend Java, et on va faire Immutable Java. Donc, ou tu peux faire du Java, mais il y a certaines choses qui sont immutables, tu le décris dans le système de type, et il y a quelque chose qui va le vérifier. Alors, question à 1000 dollars, est-ce que Immutable Java peut appeler Java ? Non, parce que moi, j'ai mon objet immutable et je veux qu'il y ait des garanties immutables dessus. Si j'appelle du Java classique dessus, le Java classique, non seulement il peut modifier l'objet, il peut garder une référence mutable quelque part, il peut massacrer tous mes invariants. Parce que le Java normal, lui, il ne sait pas que cet objet est censé être immutable. Donc, ton immutable Java ne peut pas appeler Java. Manque de bol, ça, ça inclut la librairie standard. Tu commences à faire la gueule. t'as une version de Java où t'as pas de librairie standard tu peux pas appeler du Java donc après tu te dis est-ce que Java peut appeler, immutable Java bah non pareil parce que s'il passe une fonction tu pourrais passer un truc immutable, il pourrait, casser tes invariants etc donc t'as le même problème donc en fait si je prenais Java et je fais une version immutable de Java je vais me retrouver avec un machin qui est parfaitement complètement incompatible avec Java donc aucune librairie, un écosystème complètement différent. Alors oui, ce qui va être bien, c'est l'IDE et ce genre de choses, etc. Très bien. Mais c'est tout, quoi. Et donc, c'est là où je me suis dit, il ne faut pas essayer de le plaquer sur un langage existant. Malheureusement, parce que moi, c'est plutôt ma philosophie. Il faut éviter de faire des langages autant qu'on peut. Mais j'ai dit, bon, là, je suis contraint à forcer. Il faut vraiment que je fasse un langage, parce que même si je décide de ne pas faire un langage, en fait, je vais quand même faire un langage, parce que je vais me retrouver avec un machin qui n'est pas du tout compatible avec Camel, donc ça ne sert à rien.
Bruno:
Ce sera juste une autre version de Camel ?
Julien:
Alors, version, non, parce que version... Ouais, ouais, alors si tu veux appeler ça version... Moi, pour moi, quand ta version est complètement incompatible avec le reste, c'est autre chose, si tu veux. Et c'est pour ça aussi que je ne voulais pas que Hack s'appelle PHP Extension, parce que Hack n'est ni un sous-ensemble, ni un super-ensemble de de PHP. Et donc, je trouvais que c'était se moquer de la communauté PHP en appelant ça PHP quelque chose.
Bruno:
Tu vois.
Julien:
Parce que moi, je fais du PHP, tu me vends un PHP quelque chose, bah je m'attends à ce que tu supportes PHP, quoi. Et donc, nous, de manière très délibérée, il y avait des choses qu'on ne voulait pas supporter. Et donc, on était nis, tu vois, sous-ensemble. Et donc, on a dit, on est un dialecte de PHP, tu vois. Et donc, Skip, ouais, je me suis mis à faire skip parce que je me suis rendu compte que j'avais besoin d'un langage pour faire du réactif vraiment efficace. Et voilà, c'est comme ça que j'en suis arrivé là.
Bruno:
Donc tu te retrouves en fait à créer un langage qui, au final, t'as ton, Peut-être que je me trompe encore une fois. Moi, je suis très novice. Je suis très mauvais par rapport à tous mes invités. Je l'ai complètement intégré et assumé. Si je comprends bien, avec Skip, tu as un super garbage collector qui va être capable de gérer aussi bien la durée de vie de tes variables que la durée de vie de ton cash.
Julien:
Alors, ouais, c'est pas mal. C'est une manière de dire les choses. Le problème, c'est qu'avec garbage collector, le mot, il est assez loaded, donc je pense qu'il y a beaucoup de gens dans la tête, ils imaginent quelque chose et en fait en skip, le modèle mémoire il est fait de, il a de bonnes propriétés grâce au langage, ce qui est assez rare, normalement les garbage collectors c'est un truc que tu fais vraiment à part et tu te soucies pas trop de comment marche le langage et tu t'écris ton truc à côté donc nous...
Bruno:
Et d'ailleurs assez souvent quand tu utilises le langage tu te soucies assez peu comment fonctionne ton garbage collector ? C'est des questions que tu ne te poses pas souvent.
Julien:
C'est ça. Le jour où tu te les poses, en général, tu ne sais pas quoi faire. C'est-à-dire qu'une fois que tu as ton gros machin Java et puis tu as le GC qui se met à patiner, tu ne sais pas... Enfin, si, tu peux un peu tuner à droite à gauche, mais en fait, tu es un peu coincé.
Bruno:
C'est déjà trop tard.
Julien:
Parce que c'est déjà trop tard. Donc, en fait, le problème des garbage collectors, de manière générale, c'est qu'ils ont des problèmes de latence. C'est-à-dire qu'un garbage collector, c'est super parce que je n'ai plus besoin de... Alors, d'abord, je n'appelle pas garbage collector reference counting. Pour moi, quand je dis garbage collector, je veux dire tracing collector. Reference counting, quand j'emploie le terme reference counting, pour moi, ce n'est pas un garbage collector traditionnel. Quand je dis GC, là, je dis mark and sweep, tracing, stop and copy, ce genre d'algo. Et donc, ce genre d'algo, leur problème, c'est qu'ils ont un problème de latence. C'est-à-dire que moi, j'essaye de faire un truc avec une latence faible. Par exemple, je fais un jeu vidéo où je fais du high frequency trading. N'importe quoi, la latence est importante. Écrire le programme qui va faire le rendu dans un langage garbage collecté, c'est s'exposer à beaucoup de risques. Parce qu'en gros, le GC peut prendre un temps arbitraire. Alors pourquoi ? Le problème, il est simple. le problème c'est que. En fait, t'as un tas et ton algo de tracing JIT, il faut qu'il trace ce tas. Et si ton tas, il est gros, eh ben, ça peut prendre du temps de tracer ce tas. Donc, tu te dis, c'est facile, ce qu'on va faire, c'est qu'on va découper ce tas en plus petits morceaux. Et c'est ce que font la plupart des JITs, ils ont des JITs, pardon, des GCs, ils ont des générations. Donc, l'idée, c'est de dire, alors, je sais que les auditeurs savent tout ça, mais je vais arriver à pourquoi dans le réactif c'est particulier donc t'as des générations, jeunes et donc l'hypothèse des générationnels GC c'est de dire plus un objet est jeune plus il a de chances de mourir parce que les objets jeunes meurent vite bon très bien et donc un objet ce qui va se passer c'est de génération en génération, il va être promu et plus il vit longtemps et plus il va être promu et à la fin il se retrouve dans la dernière génération et la dernière génération le problème c'est que pour la collecter celle là et ben il te faut le full major il te faut le truc qui vraiment va visiter toute la mémoire et donc nous notre problème quand on fait du réactif c'est que tu vas te retrouver avec énormément d'objets dans le full major dans la dernière génération pourquoi ? Parce qu'on a plein de caches ces caches ils restent en vie longtemps et donc ben ils se font promouvoir quoi ça reste et puis tu te retrouves avec des gigas, des gigas, des gigas et des gigas de caches alors dans la plupart des systèmes qui sont pas. Enfin dans la plupart des systèmes ils trichent, ce qu'ils font c'est que leur cache ils ne le mettent pas dans la même zone mémoire et donc du coup ils payent des copies quand ils sortent des objets du cache et du coup t'as pas ces problèmes là, mais si tu veux pas payer les copies vers le cache tu te retrouves avec un tas qui grossit, et donc quand le full majeur se lance parce que ton cache à chaque fois qu'il change en gros c'est du garbage qui ne va être collecté que quand t'as un full majeur, Et le full-major, si t'as 10, 20, 30 gigas de cash, tu peux l'attendre, tu peux aller te faire un sandwich. Moi, je sais, je connais des gens qui géraient ce genre de système dans des grosses boîtes. En fait, quand le full-major se lance, il tue la machine, quoi. Et il relance From Scratch parce que ça sert à rien. Donc, notre problématique, c'est quoi ? C'est qu'on va se retrouver avec plein d'objets qui vont vivre très longtemps. Et ces objets, si on utilise un tracing collector bête et méchant, ils vont être collectés que quand le full-major se lance. Et donc, on va avoir des problèmes de latence. Et donc, quand tu fais du réactif, ça, ce n'est pas acceptable. C'est-à-dire que quand tu fais du réactif, toi, tu veux pouvoir prédire la latence avec laquelle le système va répondre. Sinon, ce n'est pas bon. Donc, qu'est-ce qu'on a fait, nous, X-Keep ? Ce qu'on avait avec Skip, c'est qu'on a, nous, la garantie que les objets qui vont atterrir dans nos caches, d'une part sont immutables et d'autre part n'ont pas de cycle. Et donc, ces objets-là, on sait qu'on peut les gérer avec un compteur de référence et sans avoir de fuite mémoire. Parce que le gros problème du compteur de référence, c'est que s'il y a des cycles, ça devient compliqué de les détecter. Donc nous, en fait, on a un système mémoire avec deux systèmes, si tu veux. Donc ta, en gros, imagine ton programme, il part avec un ta. Ce ta, il est complètement immutable. Et ça, c'est tous les objets en cache. Et tous ces objets en cache, ils sont immutables, acycliques, etc. Nous, on prend l'update. Donc on prend les entrées qui changent pour faire une transaction. On va aller exécuter l'update. Et pendant l'exécution de l'update, Là, on va faire du GC classique sur les objets qui ont été alloués pendant l'update. Et ce GC classique, en gros, il va s'arrêter dès qu'il tape sur des objets dans le tas parce qu'il sait que c'est immutable et donc il n'a pas besoin d'aller scanner quoi que ce soit dans le tas. À la fin de ton update, quand tu as fini, tu nous donnes un nouveau tas immutable. Et donc, c'est là qu'on va faire le 5 et c'est là qu'on va mettre à jour les compteurs de référence. C'est-à-dire que c'est là qu'on va prendre le nouveau tas et on va copier ce qui doit survivre. On va incrémenter les compteurs de référence là où il faut, décrémenter les compteurs de référence là où il faut et récupérer la mémoire à ce moment là, et ce qui est intéressant avec Stalgo c'est que Stalgo il est en grand taux de ce que tu as à louer pendant l'update, il est pas en grand taux de la taille de ta mémoire et ça ça change tout, parce que ça veut dire que si tu veux faire un truc avec une latence faible ou par exemple t'es dans un jeu t'es dans un truc où tu dois répondre Donc nous, par exemple, on ne l'a pas sorti, mais on a développé une GUI qui redessine tout from scratch, point par point, en utilisant WebGL. WebGL ou OpenGL pour du natif. C'est la même logique parce que Skip, ça compile aussi vers WebAssembly. Et donc là, on avait des problématiques de latence folles, quoi. C'est-à-dire que quand tu fais du dessin, que tu dois vraiment redessiner, tu vois, tes scrollbars, tes machins, tes trucs, là, t'as des problématiques de latence qui sont très, très, très, très fines, quoi. Et donc, alors...
Bruno:
Mais attends, parce que si je comprends bien ton analogie avec l'état, donc, c'est que quand t'as ton nouveau programme qui se lance, tu régénères un nouveau tas, et après, tu synchronises tes tas. C'est ça ?
Julien:
C'est ça.
Bruno:
Mais donc, tu as quand même besoin de refaire tous tes calculs pour régénérer ton nouveau tas ?
Julien:
Non, parce que ton nouveau tas, il utilise en très grande partie l'ancien tas.
Bruno:
En fait, c'est.
Julien:
Une structure de données persistante. Donc, toi, en fait, c'est comme dans un arbre, tu vois, persistant, où si je rajoute un élément, la différence entre le nouvel arbre et l'ancien arbre, c'est log de haine, nœud, dans le truc. Donc là, c'est la même idée. C'est-à-dire que toi, tu as ton ancien tas, tu me donnes ton nouveau tas, mais en fait, ton nouveau tas, il est aussi mutable. Donc comme tu n'as pas pu modifier l'ancien tas, ce que tu as fait, c'est que tu as certains trucs qui ont été alloués dans ta mémoire actuelle, ta nouvelle mémoire que tu viens de créer. Et tu as des pointeurs qui viennent pointer vers l'ancien tas. Et donc là, on peut faire la synchro. Alors, j'ai simplifié Amor parce qu'en fait, il y a plusieurs threads et chacun peut se retrouver avec des versions différentes du tas. Il y a des problèmes de concurrence intéressant, alors moi ce que j'aime bien avec le réactif c'est que ça change complètement la manière dont on fait la concurrence on peut en parler si tu veux alors la concurrence normalement la concurrence, la manière dont ça marche c'est que t'es dans un état. Donc je vais faire de database 101. Je pense que ça va bien faire rigoler les gens qui connaissent les bases de données. Mais en gros, voilà, ta base de données, elle est dans un état. Tu prends une transaction et à la fin de ta transaction, tu fais ton commit, tout rentre. Et puis, ce qui va se passer, c'est imaginons que pendant que tu es en train de faire ta transaction... Alors, pour faire ta transaction, tu as des locks à différents niveaux et tu as un journal. C'est-à-dire que ton problème, c'est que quand tu vas prendre des locks qui sont à des niveaux bas, qui sont à des niveaux très fine-grained, tu peux te retrouver dans des conditions de deadlock. C'est-à-dire que tu peux te retrouver dans une condition où tu as loqué ça, maintenant tu essaies de loquer ça et tu as une autre transaction qui essaie de faire le machin symétrique, enfin dans l'autre sens, tu vois. Et tu te retrouves bloqué. Et donc, dans ces cas-là, il va falloir faire un rollback. Pour faire le rollback, il faut avoir un journal. Le journal, pour l'avoir écrit, enfin, pour écrire ce genre d'algo, je peux te garantir qu'il a intérêt à savoir comment marche un système de fichiers. Ce n'est pas donné à tout le monde. Et donc, en gros, ton algo, c'est à une... Et puis après, bon, si vraiment, à chaque fois que tu essaies de faire ta transaction, il y a quelqu'un qui te bloque, au bout d'un moment, tu prends un gros log global et tu dis, vous m'emmerdez tous, moi, je vais passer ma transaction. Et ça se voit quand on fait, quand on manipule des bases de données. Quand tu manipules des bases de données, tu vois bien que des fois, t'as des grosses, bonnes, grosses transactions. Quand tu les lances, ça pique pour le reste du système. Tu vois bien qu'il y a un truc qui s'est passé. Et nous, en fait, avec le réactif, on s'est rendu compte qu'on pouvait complètement revisiter la manière dont fonctionnait le concurrent. Alors, je vais t'expliquer pourquoi. Alors, imaginons, t'es dans un état et t'as deux freds qui partent en même temps faire popote dans leur coin. Ils vont faire leurs transactions. Donc, j'étais dans l'état S0. Maintenant, il y a un fret qui part. Il me redonne l'état S1. », Dans l'état S1, pour moi, c'est facile. Je dis, j'étais dans l'état S0, maintenant, je suis dans l'état S1. Je prends un lock, je fais le commit. Tac, maintenant, la nouvelle tête, c'est S1. Maintenant, il y a l'autre thread qui revient et qui, lui, il dit, moi, j'aimerais être dans l'état S2, sauf que moi, j'ai fait mes calculs à partir de S0. Je n'ai pas tenu compte des changements qu'il y a eu dans S1. Donc, si on était dans un système traditionnel, je dirais, bon, ben, roll back et tu repars. Sauf qu'on est réactif. Et comme on est réactif, On est capable de dire qu'est-ce qui a changé entre S0 et S1, prendre la logique réactive et dire, écoute, tu as raté ces changements-là, donc tu les prends. Alors, cette fois-ci, sous un lock, puisqu'on ne va pas te faire traîner à chaque fois comme ça en boucle. Tu prends ces quelques changements-là, tu mets à jour ta transaction et on la prend comme ça. C'est un peu comme si tu disais aux gens, allez-y, faites des conflits, pas de problème, allez-y, faites comme si vous étiez tout seul. De toute façon quand vous reviendrez au bercail pour faire votre commit nous on sait où ils seront les conflits et c'est à ce moment là qu'on vous dira à vous d'aller mettre à jour que ce qu'il faut ça a du sens ouais.
Bruno:
Complètement j'essaye en même temps de voir des use case où c'est où c'est effectivement utile parce qu'en fait t'es quand même obligé de repartir pour faire tes calculs.
Julien:
Tu repars pas c'est incrémental c'est à dire c'est que ce que t'as raté Alors évidemment, si la transition entre S0 et S1, le gars, il a rajouté une table avec un million d'éléments. Oui, ça va te coûter un bras. Mais la plupart des transactions, c'est code. Et la plupart des transactions, déjà, il n'y a pas de conflit. Et quand il y en a, c'est des conflits très simples. C'est des choses, c'est quelqu'un qui a mis à jour une toute petite donnée qui va te coûter absolument rien à mettre à jour de l'autre côté. Et le worst case, de toute façon, le worst case, c'est déjà ce qui se passe. Le worst case, c'est tu vas roll back et refaire. Donc, c'est pas pire que ce qui se passe aujourd'hui.
Bruno:
Parce qu'en fait, si... J'essaie de prendre un cas très simple sur cette gestion de la concurrence. Mettons, tu as un livret de comptes en banque. Tu as deux personnes qui vont faire leur retrait en même temps. Tu as effectivement la majorité des cas où tu as ces deux personnes qui vont retirer de l'argent sur des comptes différents. Et donc, le deuxième qui arrive, il n'y a pas de concurrence directe avec l'autre. Donc, il peut recommitter son changement. Mais dans la mesure où... Donc, si je comprends bien, c'est dans la mesure où tu as deux personnes qui font un retrait sur le même compte, il faut que le deuxième quand il commit son virement, tu prennes en compte le changement de solde impacté par le premier. On est d'accord. Ma question c'est, comment tu fais ? Qu'est-ce qui change dans ma manière de programmer ? La manière dont moi je vais faire tout mon algorithme de retrait de fonds. Qu'est-ce que je dois changer pour que sur ce rerun, je ne modifie que ce petit élément. C'est ce truc-là que moi, j'arrive pas à capter.
Julien:
C'est-à-dire qu'en fait, quand tu fais de la programmation réactive, tu fais pas... Tu fais pas... T'es pas en train de modifier des choses à la main. En fait, ce que tu fais, c'est que toi, t'établis un graphe de calcul. Et ce graphe de calcul, nous, ensuite, on va le prendre et on va s'en servir pour dériver un programme qui se met à jour. Exactement comme en React. En React, t'es pas en train de modifier les composants t'es en train d'expliquer ce que tu veux voir à l'écran et je sais que c'est difficile, alors c'était difficile en React maintenant il y a beaucoup de gens qui s'y sont habitués mais au début React quand c'est sorti pour le coup moi j'étais à Facebook et je connais bien les gens qui ont fait React, et les gens détestaient ça parce que vraiment ça te change complètement la manière de réfléchir c'est à dire quand t'es programmeur t'aimes bien visualiser. Pour moi, c'est ça la différence entre un programmeur et un non-programmeur, c'est qu'un programmeur, il visualise l'état de la mémoire. C'est ça vraiment qui fait la différence. C'est-à-dire que je te donne une boucle et dans sa tête, le programmeur, il voit le X qui se met à jour, il voit le programme se dérouler, si tu veux. Et c'est très difficile quand un paradigme arrive... Et te dit arrête de réfléchir comme ça, arrête de réfléchir en termes de quand tu cliques tu vas faire ci, non, tu réfléchis t'as tes composants, ils sont figés et maintenant tu m'expliques comment ils sont et la programmation réactive c'est pareil, c'est pour ça que souvent t'as des gens qui arrivent qui viennent du streaming, qui viennent de la base de données, qui viennent d'autres trucs, dit bon alors quand je reçois mon événement bon comment je dis à mon truc que, non, y'a pas d'événement, il faut pas que tu raisonnes comme ça toi t'es en train de dire voilà, telle valeur sur tel compte en banque c'est le résultat de telle fonction appliquée à telle autre valeur sur tel autre compte et point barre et c'est tout et il y a un lien qui est fait entre les deux alors évidemment quand t'es en phase d'écriture il faut bien que t'écrives alors je pense que l'exemple du compte en banque c'est un cas un peu pathologique parce que là il faut que t'écrives et quand t'es en train d'écrire, le réactif t'aide pas plus que ça. Il faut que t'écrives en même temps. Bon, il te faut un truc qui gère l'écriture en même temps. Par contre, quand t'es en train de décrire un système beaucoup plus complexe. En fait, il faut que t'arrêtes de raisonner en termes d'événements et en termes d'écriture. Et il faut vraiment que tu imagines des liens sémantiques entre les différents composants. Donc, t'es pas en train de te dire j'ai reçu un message de l'API machin qui me dit que tel truc a changé, tout ça, ça ne t'intéresse pas. Toi, tu ne programmes pas comme ça. Toi, tu dis, je veux que l'API machin me donne tel résultat. Et si ce résultat venait à changer, ce n'est pas mon problème. Donc, pour répondre à ta question, quand tu écris dans un style réactif, ce genre de questions-là, tu ne te les poses pas. De la même manière que quand tu es en train d'écrire un truc de rendu en React, tu te poses pas la question de comment ça va être mis à jour dans le DOM.
Bruno:
Ok donc en fait ça veut dire que avec Skip tu te poses, Tu portes un... Attends, j'essaie de former ma question en même temps, mais parce qu'en fait, la compréhension que j'ai, c'est que tu portes une grosse partie de la complexité, qui permet en fait qu'au final, moi, j'écrive quasiment pas de ligne de code, et que c'est en fait Skip qui va porter nativement toute cette complexité et qui fait tout ça...
Julien:
Concurrence et invalidation de cache. Voilà ce qu'on va faire pour toi. Donc après, si t'aimes écrire ces choses à la main, mais effectivement dans un système distribué, dans un système concurrent, il y a beaucoup de gens qui viennent taper en même temps, tous les problèmes ils sont là c'est à dire que si je te demande de me faire un système avec trois machines qui communiquent, tous tes problèmes vont être là quoi, c'est bon bah qu'est-ce qui se passe quand ils arrivent en même temps quand lui il arrive avant lui et surtout qu'est-ce qui se passe sémantiquement c'est à dire que comme les raise conditions le problème c'est que t'arriveras pas à exercer tous les chemins possibles, et le pire des scénarios et c'est ce qui se passe tout le temps, c'est que la plupart du temps, ça marche, jusqu'à un beau matin où un truc arrive avant la mise à jour de machin et puis, les invalidations de cash, c'est pire. C'est-à-dire que souvent, ça marche et quand c'est faux, on se rend compte très très tard que c'est faux parce que tu as utilisé un truc outdated mais les trucs outdated, ils ont les bons types, ils ont des valeurs qui ressemblent à quelque chose de correct Donc, c'est très, très difficile de... Souvent, les bons invariants. Donc, c'est très, très difficile de détecter que tu t'es planté dans ton cache.
Bruno:
Tu détectes seulement quand la différence devient flagrante, quoi. Pas la divergence.
Julien:
Pas tant que ça, en fait. Parce que moi, ce que j'ai remarqué dans ce genre de système-là, c'est que tu remarques quand c'est trop tard. C'est-à-dire que tu vois bien qu'il y a une valeur qui n'est pas la valeur qu'elle devrait être. Mais comme tu n'as pas la séquence de read et de write qui a mené à cette valeur, en fait, c'est très, très difficile pour toi de déterminer comment t'en es arrivé là, en fait. Parce que quand t'as une exception, c'est simple. Une exception, t'as une backtrace et donc tu peux tracer ce qui s'est passé. Quand une valeur n'a pas la bonne valeur à cause d'une mauvaise écriture, ça dépend. Si la source est simple et qu'il n'y a qu'une personne qui écrit à cet endroit-là, là c'est assez facile mais quand il y a beaucoup d'endroits différents qui interagissent avec cette valeur, et ben tu te dis, ben là tu te grattes la tête et tu te dis mais merde comment ça se fait que je me suis retrouvé et puis c'est très difficile à.
Bruno:
Débuguer c'est.
Julien:
Très difficile de programmer ce genre de choses.
Bruno:
Avant de commencer l'épisode on avait une petite discussion autour de PHP et de hack ce que je te partageais c'est que, toi forcément chez Facebook t'as vu des contextes d'usage du PHP qui sont disproportionnés par rapport au commun des mortels qui ont nécessité d'en arriver à inventer hack est-ce que de la même manière avec Skip tu couvres en fait des use cases des problématiques qui en fait vont concerner des cas, assez peu courants, tu vois quand on parle de tout sujet de concurrence, effectivement d'une gestion aussi fine de la notion de cache ça correspond pas à beaucoup d'usages En tout cas, l'impact de ces phénomènes-là est peu visible sur la majorité des échelles ?
Julien:
Alors, ça dépend. Je pense que c'est un problème que les gens ne savent pas qu'ils ont parce qu'ils ont toujours fait autrement. Donc, c'est un peu comme si... C'est un peu comme si t'arrivais à une époque où tous les jeux vidéo étaient en 2D. Et puis, toi, tu fais le premier moteur 3D. Et puis, le mec te dit, ça sert à quoi ton truc ?
Bruno:
Ça marchait bien en 2D.
Julien:
Ça marchait bien en 2D. De toute façon, tous les jeux vidéo sont en 2D. Donc, c'est un peu niche, ton truc, quand même. Et en fait, ce qui se passe, c'est que je pense que la bonne réponse, c'est de dire, ben non, est-ce que les gens ne faisaient pas de 3D ? C'est parce qu'ils n'avaient pas la puissance de calcul. C'est pas parce qu'ils ne voulaient pas faire de 3D. et donc je pense que dans le réactif c'est un peu pareil, c'est à dire que, combien de fois si tu vas voir un dev un dev frontend et tu lui dis voilà tu pourrais avoir tous les objets qu'il faut pour faire cette vue là en fait pour faire toutes les vues de l'utilisateur machin chose et tous ces objets, vont être maintenus à jour tout le temps, côté client, pour toi il signe tout de suite le problème, alors pourquoi il ne l'écrit pas il écrit pas parce que c'est l'enfer parce que pas à écrire qu'est-ce qu'il va falloir qu'il fasse alors d'abord faut aller côté serveur, alors côté serveur il a du PHP, il a du machin, il faut faire popote du piton, ce que tu veux ensuite il va se gratter la tête, il va dire oui mais bon maintenant les sources de changement c'est quoi ça peut être ma base de données, ça peut être des services ça peut être plein de trucs, et imaginons qu'il y arrive, ça va lui coûter un fric fou parce qu'en gros à chaque fois que sa base de données va changer, il va se remettre à calculer un milliard de trucs, etc et ça va être l'enfer à débuguer parce que si la valeur ne se met pas à jour. Comment tu vas aller voir ce qui s'est passé, etc. Donc moi, je pense que ce n'est pas tant que ces niches et qu'il n'y a pas beaucoup de cas d'usage, c'est que les gens se sont habitués à faire autrement. Alors après, ça dépend. Moi, par exemple, j'avais parlé de l'impact et l'attrait du réactif pour faire du côté client avec un collègue qui faisait du JavaScript. Et il me disait, mais ça sert à quoi ? Pourquoi tu ne fais pas refresh ? Alors je disais, il y a quand même pas mal de cas de figure où tu n'as pas envie de faire refresh. Tu as envie de faire des trucs plus live, plus tout est à jour c'est sexy en ce moment on parle beaucoup de local first, dans cette communauté là et c'est des communautés qui sentent bien qu'on a des puissances de calcul absolument monstres et on a des latences horribles on est toujours à cliquer sur un truc sur le serveur, ça patine pendant 3 secondes alors que le client il pourrait faire tout ça, et donc si tu fais partie de ces gens, alors je dis pas toi mais je dis en général, ou quand je te dis avoir une latence de quelques millisecondes sur toutes tes actions sur ta GUI ce serait quand même top et que ta réponse c'est beau moi je rafraîchis. Oui effectivement là moi je peux pas discuter parce que le réactif c'est de la latence c'est quand tu veux manger de la latence sur les choses que ce soit sur le client que ce soit sur le serveur que ce soit alors il n'y a pas que la latence mais c'est un enjeu et donc pour répondre à ta question, je pense qu'il y a plein alors autre exemple côté serveur, Il y a plein de cas où tu aimerais pré-calculer un cache. C'est-à-dire que tu as des objets, tu sais que tu vas les utiliser tout le temps, tu sais que ça te coûte un bras de les calculer, mais tu ne le fais pas parce que si tu introduis un cache, tu as deux mauvais choix. C'est-à-dire que soit tu mets un cache, mais tu as besoin que ces objets soient vraiment à jour et donc tu vas mettre un time to leave très très court et donc ton cache ne va pas servir à grand-chose. Soit tu décides d'avoir un time to live long, mais là il va falloir que tu te fasses l'invalidation à la main et t'as pas envie de risquer le truc et donc tu le fais pas donc ça c'est un autre exemple côté serveur où ce serait bien pratique d'avoir tous les objets dont t'as besoin dans un cache pré-calculé, maintenu à jour voilà, donc des exemples comme ça il y en a plein et je pense que la raison pour laquelle les gens font pas c'est pas parce que c'est niche ou qu'il y a pas trop du use case c'est parce que on a pas trop les stacks on a pas trop les technos pour faire ça donc ils feront autrement.
Bruno:
Tu faisais l'analogie avec les jeux vidéo en 3D à l'époque des jeux vidéo en 2D. Je vais me permettre de rebondir sur cette analogie-là. Certes, je sais que tu as créé Skip il y a un moment maintenant, mais on voit aujourd'hui avec l'émergence des IA, on voit cette arrivée des systèmes full agentiques avec une perspective de peut-être même voir complètement disparaître le code, pas juste se dire que c'est les machines qui vont générer le code à notre place mais carrément qu'il n'y aura plus de code c'est juste des agents qui vont parler entre eux est-ce que ça a encore du sens aujourd'hui, d'aller créer des nouveaux langages qui vont aller adresser des nouveaux use cases là où en fait demain potentiellement ce sera en fait juste des agents qui parlent entre eux.
Julien:
Alors ouais question compliquée alors il y a deux scénarios il y a le scénario l'IA. Est plus forte que les hommes, surtout. Donc, si on est dans un scénario où les IA sont plus intelligentes, plus rapides, dans absolument tous les domaines, mathématiques, physique, ingénierie, tout ce que tu veux. Donc là, effectivement, avoir des langages, la seule chose que je vois qui pourrait être utile, c'est pour le contrôle. C'est-à-dire que j'imagine un monde où les IA génèrent tout. Il y a peut-être certaines choses où on aimerait bien avoir le contrôle de comment ça marche. Et donc, ça pourrait être utile d'avoir encore des langages dans ces choses-là. Je pense peut-être aux militaires, ce genre de choses. Alors, peut-être pas forcément parce qu'ils ne font pas confiance aux IA, mais peut-être parce qu'ils auraient peur que l'IA qu'ils ont utilisé était corrompu par un autre gouvernement, ce genre de choses. Donc, je pense que de toute façon, il y aura toujours de la place pour les outils humains pour faire du critique, du très, très critique, où on a un vrai besoin de contrôle. Après, combien il y en aura si vraiment on était dans ce monde-là ? j'en sais rien. Mais je pense que ce monde-là, si on y va... C'est pas demain. On a probablement un monde hybride qui nous attend, où on va avoir des outils, des IA qui peuvent nous assister, qui peuvent faire des choses pour nous. Et nous, humains, on se sert de ces IA comme d'un outil. Et donc là, pour moi, non seulement il y a tout à réinventer, donc oui, des langages peut-être, mais aussi des outils, surtout. Et je trouve ça super excitant parce que j'adore faire des outils. Et je pense qu'il y a une vraie place pour le réactif parce que pour ces agents, les outils, les problématiques vont devenir des problématiques de latence. C'est-à-dire que moi, j'ai toujours été obsédé par la latence pour mes outils parce que quand je code, c'est un jeu pour moi. C'est-à-dire que moi, quand je code, je veux du feedback immédiat sur ce que je fais parce que je m'amuse. Et donc t'imagines si j'étais en train de jouer un jeu vidéo et je tourne à gauche et puis 4 secondes après ça tourne à gauche c'est chiant comme la mort les latences élevées ça tue le plaisir donc quand t'es en train de jouer moi un des trucs que j'adore avec Nintendo c'est ça charge jamais tu cliques ça marche etc et donc moi mes outils j'ai toujours été obsédé par la latence parce que je veux itérer rapidement sur mon programme parce que je m'éclate parce que c'est fun tu vois, et dans les boîtes dans lesquelles j'étais jusqu'à présent ils disaient bon c'est bien gentil Julien alors à part pour PHP parce qu'il y avait une communauté qui. Eux aussi ils ne voulaient pas introduire la latence mais en général c'est bon Julien tu nous fatigues avec tes trucs de latence on attend 4 secondes, très bien, on a d'autres priorités et là je pense que le monde va changer parce que maintenant ça va être des IA, qui vont générer ces codes. Et ces IA, ce qui va être un facteur très déterminant, c'est les coûts de CPU. Donc, les IA vont générer beaucoup de codes. Ce code, il va falloir le valider, il va falloir faire plein de choses avec, il va falloir créer plein d'outils avec pour le débugger, pour faire plein de choses. Et la latence va être critique parce que ce code, il va être généré en prod. C'est-à-dire que jusqu'à présent, on vivait dans un mode dans un monde dans lequel le code qu'on génère, il était offline et ensuite on rentrait en prod. Et c'est pour ça que nos outils n'étaient pas... Les latences des outils n'étaient pas... Enfin, ce n'est pas le truc qui allait faire vriller ton CEO parce qu'il se dit, bon, ils sont bien gentils, mais ils vont attendre deux secondes et ça ira très bien. Mais dans un monde où les IA génèrent du code, probablement à la volée, parce que pourquoi pas, tu vois, eh bien maintenant, tu es en prod, quoi. Tu es en prod et du coup, tu as intérêt à aller vite. si tu fais une analyse statique moi je te donne un exemple très simple je pense que quand tu as beaucoup de code qui est généré par une IA. Les enjeux de sécurité de ton code vont être énormes c'est à dire que, est-ce que ton IA elle fait pas n'importe quoi d'un point de vue sécurité bon ben on a des analyses statiques pour faire ça sauf que ces analyses statiques au jour d'aujourd'hui, c'est faut sortir la moulinette c'est l'usine à gaz ça met 4 heures à analyser tout le truc bon ben tout ça faut le revoir en réactif alors évidemment chacun voit mais il y a sa porte mais moi je vois un monde qui change et un monde qui est pas, qu'il y a un monde qui va être excitant pour les outils et pour les langages parce qu'il faut tout réinventer. Et ça, moi, j'adore.
Bruno:
Pour terminer, toi qui as déjà créé deux langages, quels seraient tes conseils pour ceux qui ont envie de s'y mettre aussi et de créer un langage ?
Julien:
Alors, d'abord, don't do it. Première chose, c'est une réponse compliquée parce que, je vais dire, ça dépend de ce que vous voulez faire. Si vous voulez créer un langage industriel je dirais don't do it, mais des fois il faut moi je pense que mis à part skip mais bon je suis très très biaisé là dessus donc je vais mettre ça de côté mais par exemple la dernière fois qu'on a créé un langage industriel utile c'était Rust voilà Rust pour faire traquer l'ownership statiquement il y en a besoin vraiment et, si t'essayes de le rajouter. Comme un truc add-on comme a fait C++11 par exemple, avec les Unix, etc., t'as une solution incomplète. Donc, si vraiment tu veux que ta gestion mémoire soit gérée statiquement, il fallait inventer Rust. Mais, si on regarde l'histoire des langages, la plupart des temps, il fallait pas faire des langages. Je veux dire, PHP, Ruby, tous ces trucs, Python... Enfin, t'imagines si Python, Ruby et PHP, au lieu de refaire un interprèteur pourri fait de briquet de broc avec un parseur qui marche pas t'imagines s'ils avaient juste transpilé ça vers lisp ou scheme, il y avait déjà les langages dynamiques on savait très bien comment ça fonctionnait on avait déjà des jits, on avait déjà des gc on avait déjà tout ça qui fonctionnait donc si vraiment, parce que si je regarde Python aujourd'hui, Python ce que ça m'apporte c'est pas du tout dans la sémantique du langage. C'est la syntaxe, peut-être un peu comment sont gollées les librairies, très bien. Mais j'aurais très bien pu transpiler tout ça vers l'ISP. Et donc, maintenant, je me retrouvais dans un monde où j'aurais tout l'écosystème JavaScript, tout l'écosystème Python, tout l'écosystème Ruby, PHP, tout ça, ce serait le même écosystème où tout est compatible. On ne serait pas du tout dans le même monde. Donc, première chose, non, n'inventez pas des langages si vous pouvez maintenant, par exemple on peut s'intéresser à la création d'un langage pour des raisons académiques. Et donc là, je dirais, il y a deux étapes, enfin, il y a deux manières de faire. Donc d'abord, il y a les langages dynamiques. Si vous voulez faire un langage dynamique, c'est très facile, c'est très rapide. C'est des projets assez courts. Moi, je conseille à tout le monde de le faire juste pour voir ce que c'est de faire un interpréteur. Vous faites un petit parseur, vous allez ouvrir un bouquin sur comment parser, etc. Peut-être vous utilisez Triciter ou je ne sais pas. Ensuite, vous faites un petit interpréteur. C'est très bien, c'est ludique, ça va très vite. Si vous voulez faire des trucs typés un peu plus compliqués là il faut passer un peu plus de temps à lire la théorie faire des choses maintenant par exemple Inley Milner c'est très abordable, c'est la base de ML, tout ce genre d'algo là. Mais ça prend un peu plus de temps, après c'est pas le bout du monde et après si vous voulez faire un truc industriel bon bah là il y a plein d'autres problématiques, notamment les problématiques outils, c'est-à-dire que, quand si vous faites un langage académique, par exemple vous ne vous saussiez pas du tout de l'outillage parce que ce que vous voulez faire, c'est faire un papier et donc le fait que votre inférence de type, la seule chose qui va vous intéresser, c'est l'expressivité de votre système de type, c'est-à-dire combien de programmes corrects vont être acceptés par votre système de type, très bien, et quand on est académique, c'est ça qu'il faut, donc je leur jette pas la pierre, sauf que quand vous voulez faire un langage industriel, bon, ça, c'est une propriété de votre système de type, mais il y en a plein d'autres. Par exemple, est-ce que autocomplete fonctionne bien ? Est-ce que je peux faire des outils de refactoring facilement ? Est-ce que... Etc. Etc. Tout ce qui fonctionne avec une IDE et tout le tintouin. Et donc, ces problématiques-là, ça, c'est très long. C'est très long et à moins de bosser dans une boîte qui a ce genre de problème. De toute façon, c'est le problème auxquels vous ne serez pas confronté. Donc je dirais les gens qui veulent se frotter un peu à comment faire un langage, je leur conseillerais de faire un coup de Inle et Milner pour faire du typage et faire un petit interpréteur. Et s'ils peuvent, faites-le dans un langage fonctionnel, parce que c'est des. Écosystèmes qui sont plus friendly à l'apprentissage de langage. Donc faites-le en camel, faites-le dans ce genre de choses, en F sharp, ce que vous voulez.
Bruno:
Et qui de ceux qui veulent faire des langages type brainfuck ?
Julien:
Ah ouais, alors là, ça c'est... ça c'est un autre challenge mais ça bon là on s'amuse donc là il n'y a pas de problème et là vous faites ce que vous voulez effectivement donc brainfuck ils n'avaient pas un jump à l'envers c'était un truc où je confonds, peut-être que je confonds il y avait des features, très particulières.
Bruno:
Alors je le connais je ne le maîtrise pas suffisamment pour répondre à cette question je te laisserai l'expertise.
Julien:
Non mais je ne me rappelle pas bien en fait c'est un pote qui m'avait montré ça j'ai pas passé beaucoup de temps ok.
Bruno:
Merci beaucoup en tout cas Julien pour cette discussion.
Julien:
Je t'en prie.
Bruno:
J'ai deux questions pour toi avant les questions rituelles du podcast avant de terminer pardon la première c'est est-ce qu'il y a un contenu que tu souhaiterais partager avec l'ensemble des auditeuristes.
Julien:
Ouais alors je vais faire évidemment ma promo, aller voir skiplabs.io pour voir comment on peut faire de la programmation réactive, évidemment parce que je suis obligé de C'est mon bébé. Sinon, moi, j'aimerais bien recommander aux gens un bouquin qui m'a beaucoup marqué quand j'étais plus jeune, qui s'appelle le COQ Art, par Yves Berthaud et Pierre Casteran. Donc, pour les gens qui ne connaissent pas, c'est COQ, c'est COQ, je crois que ça a changé de nom récemment. Mais c'est quelque chose qui permet de faire des programmes dans lesquels alors ça permet aussi de faire des preuves mathématiques vérifiées par un ordinateur mais pour un informaticien bon ça c'est peut-être moins intéressant ce qui va être intéressant c'est que ça permet de faire des programmes où les types sont riches au point de contenir tous les mathématiques, donc c'est à dire que là vous êtes en train de faire du PHP vous tapez int vous dites voilà c'est un int mais c'est pas un int ou un float, donc là imaginez que vous puissiez dire, cette fonction elle retourne des nombres premiers, et donc vous pouvez définir dans le type de la fonction ça retourne des nombres premiers et non seulement c'est correct mais c'est vérifié par une machine et votre type vous pouvez mettre ce que vous voulez vous avez tous les mathématiques. Et donc, c'est assez fou. Et ce que j'aime avec ce bouquin, qui est un bouquin qui a été écrit par des Français, Cocorico, c'est que c'est un bouquin où il n'y a absolument aucun prérequis. Donc, vous partez. Si vous avez juste codé un petit peu dans le langage que vous voulez, il n'y a pas besoin d'apprendre. Ils vont tout, ils vont vous tenir par la main et vous montrer comment on peut écrire un système où vous avez prouvé que votre programme était correct selon certaines propriétés. Et c'est assez fascinant. Et je sais qu'il n'y a pas beaucoup de gens qui vont voir ce genre de choses. Mais allez voir si vous avez le temps.
Bruno:
On mettra bien évidemment le lien en description. Et dernière question, de loin la plus importante de ce podcast. Est-ce que tu es plutôt espace ou tabulation ?
Julien:
Alors, si vous accueillez des gens qui sont tabulation, je sors tout de suite. Parce que non, je suis espace. Je suis espace un peu sans raison. Plus parce que j'avais des IDE, des éditeurs qui mettaient des espaces. Je ne me suis jamais trop posé la question. Je suis espace, plus.
Bruno:
Ok, très bien. Merci beaucoup, Julien.
Julien:
Je t'en prie, merci à toi.
Bruno:
Et merci à tous d'avoir suivi cet épisode. J'espère qu'on vous a donné des idées pour créer un langage, mais surtout des idées, des arguments pour ne pas en créer. En tout cas, allez tester Skip et cette programmation réactive, si vous n'avez pas eu l'occasion de vous frotter plus en détail avec React. Toujours intéressant de s'acculturer, de découvrir comme ça d'autres paradigmes. Je vous remercie aussi comme toujours de partager ce podcast autour de vous. N'hésitez pas à aller checker aussi le Tipeee si vous avez envie de participer et de soutenir ce podcast. Je vous souhaite une très bonne fin de semaine. Je vous dis à la semaine prochaine et d'ici là, codez bien !