Acid, le lisp-like de la communauté !

Créons notre langage de programmation ! Pour le fun !

a marqué ce sujet comme résolu.

Je continue mon Edit de plus haut.

Je ne me rends pas compte de la difficulté de créer son propre bytecode, dites moi si je vise trop haut.

En soi, ça n'a pas de difficulté particulière : tu vas juste définir les instructions d'un langage intermédiaire, et écrire l'interpréteur de ces instructions (la « machine virtuelle »). En pratique, on choisit ces instructions à un niveau intermédiaire entre l'expressivité des constructions du langage originel et les performances d'un programme natif.

Par exemple, une machine virtuelle simple pourrait être une « machine à pile » qui exécute des calculs en « notation polonaise inversée ». Si ton langage source est celui des expressions arithmétiques en notation usuelle, ta compilation transformera (4 + (1 + 5) × 2) × 6 en PUSH 4; PUSH 1; PUSH 5; ADD; PUSH 2; MUL; ADD; PUSH 6; MUL. Le bytecode reste donc plus expressif que l'assembleur (même si, dans un cas aussi simple, l'assembleur ressemblerait un peu, on n'a besoin de connaître aucun détail bas-niveau de la machine pour écrire des programmes intermédiaires), mais il s'exécutera quand même beaucoup plus vite que le programme source (en l'occurrence, parce que la machine virtuelle n'a qu'à exécuter les instructions les unes à la suite des autres : il n'y a aucun calcul de priorité à faire).

Si c'est dans cette direction que tu veux partir, il faudra lire des choses sur les machines virtuelles fonctionnelles. Xavier Leroy a des slides dessus pour un cours qu'il donne, mais je ne sais pas si c'est la meilleure source (c'est des slides, donc la présentation va te manquer, et c'est pour des gens qui connaissent déjà pas mal de choses sur la programmation fonctionnelle et la compilation). Tu peux toujours les lire et poser des questions.

Edit : je ne suis vraiment pas convaincu par LLVM pour l'instant. De toute façon, si tu veux faire ça bien, il te faudra un minimum de connaissances sur les machines virtuelles, et ça va probablement te demander d'apprendre beaucoup de choses dont tu n'aurais pas forcément envie de te soucier pour un projet aussi simple. À mon avis, écrire une machine virtuelle très simple dont on maîtrise parfaitement le jeu d'instructions est à la fois plus formateur et plus facile pour commencer.

+1 -0

Je veux dire tu utilises LLVM dans un premier temps, et s'il te prend l'envie de créer ton bytecode, fais-le.

mehdidou99

Ah oui donc j'avais rien compris :-°

Par contre je pense que je vais suivre le conseil d'Eusèbe, parce que de toute façon je pense qu'il faut mieux s'y connaître un minimum en VM avant d'utiliser LLVM.

@Eusèbe: Ben tiens c'est exactement ce que je disais hier.

Sinon je pense partir sur une VM à pile parce que j'ai rien compris à la partie sur les graphes et sur la G-Machine dans The Implementation of functionnal programming languages.

Sinon merci pour les slides.

+0 -0

Je veux changer d'outil parce que la traduction en AST Python n'était pas censée être utilisée à terme. De ce que j'ai compris c'était juste un petit hack pour avoir des résultats plus vite que si on avait commencé directement à compiler nous-mêmes. Donc un jour ou l'autre on devra changer. Autant changer maintenant donc, au lieu de s'embêter avec les limites de notre méthode actuelle, non ?

On est d’accord. Si c’est juste que « l’AST Python me saoule, passons à quelque chose de sérieux », no problemo. Mais du coup, j’ai envie de dire, pourquoi continuer à programmer en Python plutôt qu’avec un langage qui t’est plus familier ? :)

J’avais juste l’impression que tu te mettais martel en tête et que tu te résolvais à contre-cœur à passer à une solution plus complexe, pour résoudre un problème (les bindings locaux) qui a précisément été écarté de la première version du langage…

Et aussi quelle est la raison pour laquelle cette fonctionnalité n'est pas dans la spec ?

AlphaZeta

Parce qu’elle n’est pas nécessaire. Tu l’as montré toi-même, tu peux obtenir le même programme en créant une lambda annexe qui ne soit pas locale à ta première lambda. C’est un peu moins joli pour programmer, mais le compilateur / interpréteur s’en trouve simplifié, au moins pour une première version. Ce qui a toujours été l’objectif de la spec. :)

Implémenter un langage qui n'a ni boucle, ni récursivité n'a que très peu d'intérêt. Ce n'est pas en enlevant de « la spec » tous les points qui sont plus difficiles qu'une traduction mot-à-mot vers Python que vous allez progresser.

Eusèbe

<Supprimé pour cause de mot plus haut que l’autre.>, mais il va falloir que t’arrêtes de critiquer un fantasme, hein… À quel moment as-tu vu qu’il n’y avait pas de récursion dans la spec ? Mon code d’exemple est une putain de factorielle, à quel moment as-tu pu un seul instant imaginer qu’il n’y avait pas de récursion ?!

+4 -0

Pardon, j'ai effectivement manqué un exemple d'une fonction récursive (au passage, c'est la longueur d'une liste, et je ne vois nulle part de factorielle, est-ce qu'on parle de la même chose ?). Cela dit, inutile de s'énerver et d'être agressif pour autant. Si mes messages t'ont choqués ou t'ont paru acides, je te présente mes excuses, mais je n'ai dit nulle part que tu avais fumé des kilos de moquette avant de pondre cette spec (qui a pourtant nombre de défauts). On peut rester calmes ?

Ceci étant dit, le reste de mes messages reste vrai, et même avec des fonctions récursives, chercher à suivre la spécification à la lettre reste à mon avis une erreur. Par exemple, tu as enlevé les let pour simplifier l'implémentation, mais en rajoutant un système de types (pas très bien spécifié, mais on devine assez bien ML) qui est nettement plus complexe à implémenter correctement.

+1 -1

Ôte-moi d’un doute… Quand tu parles de la spec, et que tu la critiques, tu ne parles pas de ça, j’espère ? Parce qu’elle a bien changé depuis… De même que le code d’exemple.

Il va falloir te faire à l’idée : Acid est un langage fonctionnel, aussi « pur » que possible, avec des types algébriques. C’était le deal dès le départ, et à partir de là, on essaye d’arriver à ce résultat avec un système aussi simple que possible. Point barre. Tu peux continuer à ânonner inlassablement qu’on est trop nuls/ignorants/ce-que-tu-veux pour y arriver, cela n’y changera rien : c’est l’objectif fixé et les participants motivés iront aussi loin que nécessaire pour l’atteindre.

Alors s’il-te-plaît, épargne ton clavier et nos nerfs par la même occasion, et restreins-toi aux messages constructifs. Tu en as écris, et c’est très bien, c’est bien la preuve que tu en es capable. Mais tout ce qui revient, quelle que soit la formulation effectivement employée, à dire « Ne faites pas ça, vous êtes trop mauvais. », garde-toi-le bien au fond de la poche. Merci. :)

+2 -0

Ôte-moi d’un doute… Quand tu parles de la spec, et que tu la critiques, tu ne parles pas de ça, j’espère ? Parce qu’elle a bien changé depuis… De même que le code d’exemple.

Si, je parlais effectivement de celle-là. Merci du lien. Cela dit, elle a beau avoir « bien changé », les points noirs restent exactement les mêmes.

Il va falloir te faire à l’idée : Acid est un langage fonctionnel, aussi « pur » que possible, avec des types algébriques. C’était le deal dès le départ, et à partir de là, on essaye d’arriver à ce résultat avec un système aussi simple que possible. Point barre.

« C'était le deal », donc toute volonté personnelle de faire autrement doit se heurter à un refus parce que « c'est pas dans la spec, point barre » ? Pourquoi cherches-tu à tout prix à imposer à tout le monde ce genre de contraintes ?

Tu peux continuer à ânonner inlassablement qu’on est trop nuls/ignorants/ce-que-tu-veux pour y arriver, cela n’y changera rien : c’est l’objectif fixé et les participants motivés iront aussi loin que nécessaire pour l’atteindre.

La question n'est pas d'être trop nuls ou ignorants pour y arriver, la question est de faire les choses dans le bon ordre. Tu veux faire implémenter par des gens qui n'ont jamais touché de fonctionnel de leur vie à part les lambda de Python un langage fonctionnel typé spécifié par quelqu'un qui ne maîtrise pas les outils nécessaires à une spécification correcte. Comment veux-tu que vous ayiez la moindre chance d'y arriver tel que c'est parti ? Ce n'est pas une question d'être « nul », tout le monde débute un jour. Mais normalement, quand on débute, on accepte les conseils au lieu de se braquer.

Contrairement à ce que tu sembles croire, mon but n'est ni de vous critiquer, ni de faire échouer le projet. Au contraire, je cherche à vous guider pour que vous ne tombiez pas dans des erreurs qui me semblent évidentes mais que vous ne voyez manifestement pas. Maintenant, je ne force personne à suivre mes conseils : si vous voulez que je vous « laisse avancer comme on veut, quitte à se planter parce qu'on ne sait pas où on va », allez-y ! Mais ça ne semble pas être le cas de tout le monde, donc tant que quelqu'un pose des questions, j'y répondrai. Si ça te déplaît, tu n'es absolument pas obligé de considérer que ça s'adresse à toi, et tu es parfaitement libre d'implémenter le langage que tu veux de ton côté. Aie au moins la courtoisie de laisser ceux qui veulent discuter le faire tranquillement au lieu de hurler dès qu'on envisage de faire quelque chose différemment de ta spécification.

Alors s’il-te-plaît, épargne ton clavier et nos nerfs par la même occasion, et restreins-toi aux messages constructifs. Tu en as écris, et c’est très bien, c’est bien la preuve que tu en es capable. Mais tout ce qui revient, quelle que soit la formulation effectivement employée, à dire « Ne faites pas ça, vous êtes trop mauvais. », garde-toi-le bien au fond de la poche. Merci. :)

Si tes nerfs ne peuvent pas supporter que je donne mon avis, je t'invite à prendre quelques jours de pause. Tu es depuis un certain temps le seul à réagir de façon aussi agressive ici quand j'écris, peut-être qu'à un moment il faut te remettre un peu en question.

Ensuite, si tu lis « ne faites pas ça, vous êtes trop mauvais », je t'invite aussi à souffler un peu et à relire mes messages quand tu seras un peu plus calmé. Ils disent à peu près tous le contraire, à savoir « commencez par cette étape avant d'attaquer bille en tête le problème originel sans organisation, c'est le meilleur moyen d'y arriver ».

+3 -1

Pour en revenir à cette histoire de VM, je me pose une question de béotien : est-ce qu'une VM à pile (comme celle de Python) est capable de supporter un langage fonctionnel ?

Grosso-modo, quelles sont les différences entre une simple VM à pile et une VM fonctionnelle ? J'ai vraiment l'impression qu'il y a deux univers séparés entre les deux façons d'aborder la compilation, et je n'ai jamais réussi à trouver un point de convergence, alors que celui-ci doit nécessairement exister…

+2 -0

Je ne connais pas tellement la VM de Python, mais je ne pense pas qu'il y ait une opposition fondamentale entre « VM à pile » et « VM fonctionnelle ». Par exemple, la VM de Caml (je ne sais pas à quel point c'est à jour par rapport à l'implémentation actuelle, mais ça ne change pas grand chose) est une VM à pile.

J'imagine que ce qui change, c'est le type des valeurs que tu peux mettre sur la pile (objets, fermetures, juste des entiers…) A priori, je pense que la VM de Python pourrait parfaitement servir pour un langage fonctionnel. Il manque peut-être une instruction pour effectuer un appel terminal, mais je doute que ce soit très compliqué à rajouter.

Les slides de Xavier Leroy que j'ai données plus haut t'éclaireront peut-être un peu plus sur le sujet : dans celles qui parlent de machines virtuelles, il décrit plusieurs VM fonctionnelles à pile.

+1 -0

Grosso-modo, quelles sont les différences entre une simple VM à pile et une VM fonctionnelle ?

nohar

Je suis débutant, mais de ce que j'ai compris, la différence est surtout sur la méthode d'évaluation. Dans les deux cas (paresseuse ou stricte), tu peux réduire ça de toute façon à une pile, mais dans le cas où ta VM gère l'évaluation paresseuse, tu auras quelques instructions en plus (comme UNWIND dans la G-Machine) qui s'occuperont de réarranger la pile pour que les thunks ne bloquent pas l'évaluation.

Je précise que j'ai pas non plus tout compris sur cette partie du livre de Simon P-J, cette réponse est aussi un moyen pour voir si j'ai bien compris, n'hésitez pas à me corriger si j'ai dit une bêtise :)

Perso ce qui m'intéresse, plus que d'implémenter un langage, ce serait d'implémenter une VM avec le bytecode associé et pourquoi pas une IR pour aller avec (un code à trois adresses…). C'est pour ça que je pose la question. Ça fait une paye que le sujet me démange.

+3 -0

Du coup Eusèbe, tu critique la spec en disant, entre autre, que le système de typage est bancale. Pourrais tu pointer ce qui est bancale ? (Je t'ai pas vue le justifier et ça m'intéresse car à la lire j'ai pas repéré, ton avis m'intéresse). De plus, du coup, tu partirai sur quoi comme "spec" pour ce type de langage ?

C'est vrai, ça doit être super intéressant. Si tu veux t'y attaquer sur l'autre projet (impératif), je suis en train d'écrire le front-end, il me manque le back-end. ^^

mehdidou99

Je le vois plus comme un projet independant vers lequel vous pourriez compiler n'importe quel petit langage en fait. En réalité c'est facile à faire, en une soirée tu peux avoir un truc qui marche. Mais ça m'intéresse de toucher a des features rigolotes comme la possibilité de faire nativement des appels système, celle de threader vs. Un GIL, pourquoi pas un JIT…

+2 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte