Un petit langage ZdS
Amusons-nous !
Je trouve cette personne extrêmement irrespectueuse. Dommage ce projet aurait put être sympa, je ne participerais pas, merci à cette personne
Si tu penses que cette personne en a quelque chose à foutre, tu te fourres le doigt dans l'oeil. Si tu ne participes pas à un projet que tu trouves sympa juste parce que tu es vexé, tant pis pour toi.
Ce projet peut être l'occasion d'apprendre pas mal de trucs intéressants de façon plutôt ludique. Ce serait dommage que l'expérience soit altérée pour des broutilles.
Merci de rester courtois entre vous, ce forum n'est pas une arène de joutes verbales.
Bonsoir (oui il est tard mais j'en ai profité pour voir le film Hacker qui est pas super au passage). Ce post va être mon dernier conseil pour cet atelier qui me semble toujours une bonne idée mais dont les participants ne semblent pas réellement prendre les critiques de certaines personnes en compte sur ce qui a été dit.
Cela à d'ailleurs amené des comportements sur ce forum (comme le signale @adri1) mais sur IRC aussi qui n'ont pas été plaisant. Bref, on est tous capable de faire abstraction de ce genre de dérapage et de réfléchir avec un recul nécessaire de se qui devrait être pris en compte dans cette atelier. Donc je vais expliquer ça en plusieurs points et de manière bien détaillé - ensuite, vous prenez en compte ou pas, vous êtes les seules juges.
Implémenter un langage, c'est dur
Même si tout le monde s'accorde avec ce problème qui reste l'essentiel question de la création de cette atelier, à savoir: comment faire pour que justement, cela ne soit pas dur. Il se trouve (et je me répète mais il est parfois nécessaire de faire le professeur^Wperoquet) que les idées qui se trouvent autant dans ce topic que sur IRC sont des idées, certes, intéressante mais totalement hors de portée pour un lecteur n'ayant pas forcément une expertise en informatique (qui semble être la cible de cet atelier et même, par extension, de ce site).
- Un système de type - c'est bien la pire idée. Le problème est, à la fois, bien trop complexe et contient tout autant de réponse que d'étoile sur notre beau ciel. duck-typing, système de type statique, type dépendant, polymorphisme ad-hoc ou paramétrique, système de type dynamique, implicite/inférence ou explicite. Bref, on en a pour toutes les couleurs et tout les niveaux. Entant que puriste, un système de type dépendant statique serait le meilleur pour moi mais c'est à la fois très complexe à comprendre (dédi' à ceux qui font du Coq) mais ça l'est d'autant plus à implémenter. Il ne suffit pas de copier un snippet dont le premier commentaire est
Hindley-Milner
mais bien de comprendre comment on fait et pourquoi on fait. À ce stade, je suis certains que très peu de personne sont capables de m'expliquer comment assurer la transitivité de l'unification et pourquoi il est important de l'assurer. Je suis même certains que pas mal d'entre vous ne savent pas ce qu'est la transitivité ou encore l'unification et pourtant dieux c'est que cela peut être très important. Et pour finir, même la notion de type est déjà assez complexe à partir du moment où certaines personnes considèrent encore que le C a un système de type fort (et je ne critique pas, c'est un constat qui est surtout là pour que vous vous rendiez compte que certains partent de très loin).
Alors ce n'est pas du qui a la plus grosse que je tente d'expliquer ici. Ces notions, je les ai apprise de mes erreurs justement quand j'ai tenter d'implémenter mon système de type et je me suis raccrocher à des sources qui m'ont permis d'apprendre ces notions. Le point est qu'il est complexe, de base, d'expliquer comment implémenter un système de type. Ce n'est pas insurmontable et c'est même très intéressant mais je signale que l'objectif initial est celui d'être un atelier et que ces notions dépassent non seulement la compréhension de pas mal de gens voulant participer au projet mais dépasse de très très très très très loin la compréhension du simple lecteur.
-
Compiler le langage - alors déjà, la première question est, on compile vers quoi ? Je vais m'attarder sur cette question car malheureusement elle n'est simple pour personne. Je connais la hype autour de LLVM-IR (que je connais très bien pour le coup) mais en quoi vouloir compiler vers LLVM-IR est plus approprié que compiler vers une machine virtuelle ? Ensuite, cette machine virtuelle, nous devrions la faire nous même ou nous devrions utiliser une déjà existante ? Et puis enfin, qu'elle le niveau de complexité pour compiler vers une tel cible (aide à la réponse, ça dépends de la cible premièrement). Donc là non plus, on est clairement pas aidé. Certains vont dire qu'il est préférable de compiler vers LLVM-IR étant donné que la cible existe déjà et offre pas mal de possibilité comme compiler vers du natif ou encore faire de la compilation JIT (point qui n'a pas été abordé, dieux soit loué).
-
La compilation vers LLVM-IR: même si il existe des très bons cours sur comment compiler vers LLVM-IR, il n'empêche qu'il y a pas mal de question sans réponse. La première concerne notamment pour les langages fonctionnels. On fait comment pour compiler un langage fonctionnel vers LLVM-IR ? Bah la réalité fait que ce n'est pas si simple et on vous assommera cette phase de la compilation avec le lambda-lifting et les indices de De Bruijn. Des notions relativement simple pour un initié de la programmation fonctionnel mais qui ne reste malheureusement pas évidente pour un simple lecteur. Une complexité en trop qui devrait, à mon sens, être laissé à la discrétion du lecteur (à savoir, si il souhaite vraiment compiler vers LLVM-IR). On va bien entendu passer vite fait sur la notion de SSA, en réalité, pas vraiment parce que c'est une des grosses particularités de LLVM-IR. Et bien entendu, ne parlons même pas de GC ou de savoir si on doit utiliser le GC que propose LLVM-IR ou faire son propre GC et comment interagir avec lui avec LLVM-IR (notamment au moment de l'application d'une fonction si on reste dans le cadre d'un langage fonctionnel - et ce n'est pas simple, Haskell se sont bien mangé les dents dessus).
-
La compilation vers une machine virtuelle peut aider à décomplexifié ce travail notamment avec une machine virtuelle à pile (ohoh, encore une nouvelle notion, c'est quoi au final la différence entre une machine virtuelle à pile ou à registre, l'une est meilleur que l'autre ? etc.) mais il s'agit encore de trouver une bonne machine virtuelle premièrement et de comprendre comment l'utiliser (connaître son jeu d'instruction). Là aussi, un énorme travail qu'on peut bien entendu prémâché pour en sortir quelque chose de totalement aseptisé au savoir (car oui, c'est toujours facile de copier/coller du code ou copier/coller un jeu d'instruction, encore faut il le comprendre). Là aussi, la courbe d'apprentissage est vachement rude car on y introduit une chaîne de compilation qui n'est pas forcément évidente pour tout le monde - certaines personnes n'ont même pas connaissance de cette chaîne de compilation d'ailleurs.
-
Fonctionnel, impératif ou objet ou LES TROIS! Alors commence à émerger sur IRC l'idée de 2 groupes donc un pour l'implémentation d'un langage fonctionnel, un autre pour un langage impératif. Alors la première question évidente, pourquoi deux groupes ? Fonctionnel et impératif sont si incompatible que ça ? Vraiment ? Pour le coup, j'ai réellement besoin de citer Python, Ruby, Java, C++ et OCaml (toujours le meilleur pour la fin) ? En vérité, c'est une fausse problématique dans le sens où chaque paradigme apporte son lot de complexité (je reviendrais sur l'argument de vouloir faire deux groupe à cause de cette complexité plus tard d'ailleurs). Rien que la notion d'environnement est complexe pour un débutant. La politique de scope change d'un langage à un autre, elle n'est clairement pas la même entre Python et OCaml et elle est d'autant plus différente avec C89 (oui je parle de C89 !). Alors c'est la qu'elle la meilleur ? Celle de JavaScript qui est un langage fonctionnel ayant une politique de scope prête à faire retourner dans sa tombe sur quatre génération John McCarthy ? Et c'est des nuances que beaucoup ont du mal à assimiler et qui demande parfois certaines astuces pas forcément évidentes !
-
Le fonctionnel, c'est compliqué premièrement parce que certains se retrouvent, de base, bloqué sur le problème du K-combinator. En d'autre terme, les clôtures. Surtout si on vient d'un langage comme le C, cela peut être difficile de comprendre un tel concept (et en ayant été professeur d'OCaml, je sais de quoi je parle). Cette complexité nous suit d'ailleurs plus loin, notamment avec la machine virtuelle ou comment gérer des environnements locaux associés à nos fonctions - et c'est clairement pas spontané de penser à ces problèmes et de les assimiler en peu de temps. Ce rajoute à cela la politique d'application des fonctions (ou la stratégie d'évaluation) ! Call-by-name, by-lazy, by-value ! Tant de possibilité (non exhaustif) pour de si petit homme (dont j'en fait certainement partie) qui change radicalement la façon de faire le langage et là aussi, l'un n'est pas meilleur que l'autre, évitons de discriminer des concepts qui peuvent être intéressant (comme le call-by-lazy qu'on retrouve en Haskell).
-
Je vais non plus vous parler de la complexité des objets (avec notion de constructeur/destructeur) qui demande déjà un gros prérequis sur l'utilisation d'un langage objet. Sur ce domaine, vous feriez mieux d'implémenter un C-with-class qui vous présentera toutes les subtilités du modèle objet (dans sa version la plus grossière) de C++.
-
Il semble qu'il reste une place pour le langage impératif. Et oui en effet puisque c'est celui qui se rapproche le plus de la machine (sans trop se brûler tout de même) et où la compilation peut se résumer à des optimisations qui, elles, sont complexes (comme le calcul de l'utilisation des registres qui demande à ce qu'on comprenne la coloration d'un graphe - il suffit d'un pas entre crayon de couleur et processeur).
-
Concernant la complexité de vouloir faire 2 sujets (car il est réellement question de ça) afin de décanter la complexité de chacun des paradigmes, je pense que là aussi, c'est une mauvaise solution car le lecteur va certainement pas s'amuser à implémenter 2 langages (regardez tout le travail qu'il faut déjà faire pour un langage). Cela va tout simplement splitter le résultat en 2 catégories difficilement comparable et qui vont certainement discréditer l'autre partie (et c'est clairement pas se qu'il faut faire).
-
LA SYNTAXE ! Certainement la partie la plus chiante de l'implémentation d'un langage et qui pourtant permet d'avoir un résultat utilisable. Mais ce n'est pas une promenade de santé où il suffit de copier 2-3 règles sur le cours de thizanne pour s'en sortir car on arrive très rapidement à des problèmes complexes qui peuvent paraître cependant simple puisque la majorité des langages utilisent ces constructions. C'est bien entendu sans compter l'apprentissage de la hiérarchie de Chomsky déjà pour bien comprendre pourquoi certains langages ont une mauvaise syntaxe (syntaxe que nous ne devrions pas répéter) mais aussi tout les types de parser avec leurs caractéristiques comme le parser PEG, LL, LR, LALR, LALR(k) où l'on devrait bien comprendre toute les subtilités afin de produire une syntaxe qui échappe à (espérons) toutes ces problématiques afin que le lecteur ne se retrouve pas à retomber sur la théorie des langages du Dragon Book! La syntaxe, c'est compliqué et il est d'autant plus sain de ne pas se concentrer la dessus et échapper à l'ajout d'une complexité qu'on aurait du mal à imaginer souvent.
-
On va même pas faire mention du Lexer, de la différence entre NFA ou DFA et de l'impossibilité de parser du XML avec des regex. Et tout cela bien entendu, sans même faire mention du front-end d'un compilateur que beaucoup de langage s'amusent à ré-implémenter pour le fun (tout le monde fait des erreurs).
-
La technologie … Ah, les guerres de religion, toujours aussi fun et il semble y avoir une incompréhension sur ce que certains ont dit sur l'IRC. La vérité est que personne n'impose une technologie mais que OCaml est vivement conseillé pour la création d'un interpréteur/compilateur. Certains même doute de cette assertion (peut être à juste titre) mais qui reste facilement vérifiable par la première implémentation de Rust, la spécification de WebAssembly, l'implémentation de Hack ou encore de Flow ou tout projet lié à l'analyse statique d'un langage informatique (ou encore au nombre de projet OCaml abandonné sur GitHub en lien de près ou de loin au langage informatique - powered bien entendu par notre exception française!). Cela fait quand même un paquet de projet fait par des personnes qui, je pense, sont, à juste titre, pas si bête que ça. Bref, faite de l'OCaml, ça vous fera du bien. Mais au delà de cela, il est tout aussi viable de vouloir faire son langage avec autre chose qu'OCaml (je me suis amusé à faire une Scheme en C, plus rien ne me fait peur), mais c'est forcément se fermer les portes à une ribambelle de documents sur le sujet qui utilisent … OCaml. Mais je n'ai rien contre les aventuriers voulant tester un nouveau langage pour le fun (pour apprendre ce langage au travers d'un projet qui est celui d'implémenter un autre langage !) et c'est surtout de cela dont il est question. Je pense que la communauté de ZdS est à même de pouvoir lire du code en Python, OCaml, Haskell, Rust ou C++. Selon moi, la question de la technologie utilisé est là aussi un non-problème.
Le problème de tout ce topic, La Question!
Tout ce que vous avez lu avant sert en vérité à rien car sa montre juste (dans un certain extrême) se qu'il risque d'arrivé (en soit, c'est juste une extension de vos objectifs mais avec quelque chose de plus concret). Et rien que le temps de concertation de chaque membre sur la/les spécification(s) montre que vous vous trompez tout simplement de question à la base. Je m'explique.
Un langage informatique, au delà d'être complexe dans son implémentation, c'est tout autant complexe à définir. Mon premier point le montre avec tout les choix qu'on doit se retrouver à faire et qui caractérise notre langage. Et c'est bien en cela que même si on trouve certaines ressemblances dans les langages, ils sont tous différents. Ce qui fait qu'un atelier, un tutoriel ou même livre ne peut parler de TOUTES les possibilités qui nous sont offerte lors de l'implémentation d'un langage.
Et c'est en cela que ce topic est révélateur car chacun à son point de vue, son avis (légitime, hein) sur la question de comment implémenter un langage informatique qui donne forcément lieu à des divergences et des désaccords qui vous ont poussé d'ailleurs à splitter le projet en deux (ce dernier point que je trouve contre-productif). Vous ne finirez donc pas par vous mettre d'accord car, au delà du fait que certains puissent être capable de dire des inepties pouvant potentiellement mettre l'atelier en danger (sans même que vous vous en rendiez compte) et invalider certains choix qui peuvent être totalement judicieux (comme avoir un langage fonctionnel et impératif), d'autres vont tout simplement décider de partir car ils ne se sont pas retrouver dans le projet (à leurs corps défendant) étant donné que le(s) langage(s) s'écarte de la vision qu'ils ont eux.
D'autant plus que le langage que vous voulez tant spécifier n'est pas non plus fondamentalement en phase avec le lecteur! Vous pourriez faire des choix sur lequel le lecteur n'est pas d'accord et c'est un risque que vous prenez à chaque fois que vous souhaitez rajouter quelque chose dans le langage pour le fun. Mais la définition de fun n'appartient à personne et se que je considère véritablement comme fun, c'est bien de créer mon langage - d'une certaine manière d'ailleurs, c'est se que vous faites mais en ayant l'illusion d'avoir la capacité d'être d'accord entre vous (sauf que bien entendu, ce n'est pas le cas, et rien que le fait d'avoir 2 projets le démontre).
Donc on en arrive au point nommé pour savoir qu'elle est la véritable question à se poser et pour le coup je vais mimer bluestorm que certains connaissent comme étant quelqu'un d'intelligent, diplomate et efficace. Et je ne me trompe pas disant que ce post n'est que la continuité de son idée avec ma plume. Bref, la véritable question est: comment comparer des langages informatiques ? (Ouais, ça envoie pas de la gueule).
En vérité, il n'y a pas une recette unique et possible pour faire un langage, il y en a plusieurs. L'objectif de cette atelier, ce n'est pas de présenter un langage ou on ne vaudrait pas mieux que le Tiger book (qui, pour le coup à réellement une spec d'un langage, le Tiger). L'objectif c'est de donner les moyens techniques au lecteur afin qu'il puisse goûter à toutes les saveurs des langages (multiple soient elles) et de faire son choix. Ainsi, et c'est de là où se base toute ma critique, il est pour moi contreproductif autant pour vous que pour le lecteur d'essayer de faire une spec qui va forcément omettre des points importants car ça sera vous qui aurait fait les choix techniques - mais c'est au lecteur de les faire.
Ainsi, il pourrait goûter au système de type, à la programmation fonctionnel, à tout ces points. Mais au delà de ça, au delà du simple fait qu'on puisse le diriger vers les documents nécessaires afin d'étayer son goût pour les langages, puisqu'il aura fait lui même ses choix, il en sera animé et il aura d'autant plus de raisons pour les implémenter (car oui c'est chiant de lire bêtement une recette de cuisine, il s'agit de créer ici !).
Et encore quelque chose de magnifique sur ce point, c'est la responsabilité qu'il peut gagner à faire tel choix technique ou non. Il peut se rendre compte par lui même (puisque c'est lui qui l'a implémenté) de l'impact que cela a sur son langage et donc avoir un avis définitif sur la question de savoir si c'est bien d'avoir du duck-typing ou un système de type statique (ou rien du tout d'ailleurs).
Et clairement c'est cette seule question qui est intéressante car en cherchant à trouver des points de comparaison entre les langages, on cherche réellement à comprendre ce qu'ils sont rigoureusement et c'est à ce moment précis qu'on gagne en compétence. On amène donc le lecteur à dessiner (peut être pas exhaustivement, mais après tout, il a la vie entière pour apprendre) l'idée qu'il peut avoir d'un langage informatique. C'est comme quand on mange. Il s'agit de goûter les aliments (nos épinards) afin de se faire une réelle opinion de ce que sont des aliments (j'aime pas les épinards). Et ce n'est pas en apprenant bêtement par coeur comment a été implémenter tel langage qu'on arrive à en déduire ce qui est bien et mal (selon nous, toujours) - à ce que je sache, vous avez une opinion sur les épinards pas parce que vous les avez faites mais bien parce que vous les avez goûté.
Et c'est donc en mélangeant tout ces ingrédients essentielles qu'on arrive à produire notre propre recette de cuisine, et on en est fier. Et qu'est ce qu'il y a de plus que ça ? Peut être les épinards justement.
La Conclusion
Donc je pardonne les personnes qui n'ont pas lu le premier point mais le deuxième est quand même vachement important (hein, anti-thèse, thèse, synthèse). Bref, je pense qu'au delà de certaines personnes blessées par leurs égos se permettant non seulement de faire mentions de ces problèmes sur la place publique (je parle d'ici bien entendu) et du caractère assez individualiste de chacun sur la question initiale (qui est mauvaise, cf. plus haut) - caractère normal ceci dit, encore heureux que vous ayez votre propre point de vue sur la question. On en arrive à rien et c'est de cela que je dénonce.
Premièrement, il existe des gens au delà de moi (bien entendu), qui ont une expérience dans le domaine qui dépasse peut être l'entendement - quand un chercheur vous dit qu'il faut être fou pour faire du Coq, vous placez certains axiomes sur certaines personnes bien entendu - et qu'il vaudrait mieux écouter. Alors, je sais (oui, je sais), c'est chiant d'écouter les vieux (désolé thizanne) mais notre arrogance juvénile ne nous sauvera pas des murs qui nous attendent (et qui font souvent mal tant à nos dents qu'à notre égo) en les ignorant. En ce sens, j'ai appris avec le temps (comme j'ai dit sur IRC) à fermer mon claper (pour rester plus poli) face à ces gens qui, de toute façon, en savent bien mieux que moi. Attention, je ne les mets pas sur un piédestal mais il est toujours intéressant de les écouter ou de les lires et de les faire confiance surtout. Et c'est se qui est arrivé quand on m'a conseillé lorsque j'ai voulu implémenter mon langage.
Deuxièmement, de ce que j'ai remarqué, pas mal de gens ne savent pas de quoi ils parlent au pire ou, au mieux, essayent de participer tant bien que mal au sujet (et c'est très bien). En ce sens, et c'est l'intervention qu'on a eu sur IRC, il s'agissait de faire en sorte que tout le monde sachent de quoi ils parlent. Et ceci aurait été possible si tout le monde avez pris la peine d'essayer de faire un PoC d'un langage dans son coin. Cela aurait permis notamment à ce que d'autres puissent se rendre compte de l'arnaque de certains et qu'ils puissent avoir un avis tout aussi avisé sur les questions qui ont traversé le topic et l'IRC (et que aucun puisse mettre mis à l'écart car, à vous entendre, l'avis de tout le monde compte et c'est bien).
En aucun cas, il a été dit que vous deviez faire l'atelier en OCaml (même si en ayant tester, vous vous convaincriez tout seul que c'est une bonne solution en passant) et en aucun cas il a été dit que l'atelier devait être le cours de thizanne. Il a surtout été question de mettre tout le monde sur la même bateau, c'est à dire sur les mêmes problématiques d'implémentation d'un langage jouet et cela en suivant le cours de thizanne.
Et donc troisièmement et c'est le dernier point, on est pas là pour vous bouffer. Il se trouve que certains d'entre nous viennent de très très loin et ont vu certaines choses comme des projets réussis et des projets qui ont échoué. On est donc là pour vous faire gagner du temps sur pas mal de notion afin que vous puissiez rebondir plus loin (quitte à aller plus loin que nous d'ailleurs) et en faire ressortir le meilleur. Si j'ai fait ce texte, c'est que j'ai bien compris que personne n'allait prendre en compte, non seulement mon avis, mais celui de d'autres aussi pour la simple et bonne raison que la forme n'y était pas. Maintenant, elle y est. Donc avant que vous n'interveniez sur ce que je viens de dire, je vous conseille vivement de lire et d'appliquer les conseils qu'on vous a donné (et qui prennent sérieusement pas beaucoup de temps) et ensuite, on peut réellement discuter. Ce qui est dommage, c'est que je risque de ne pas vous répondre et que je laisse ça là comme ça.
PS: J'ai même pas parlé de GC ou de machine virtuelle qu'on pourrait implémenter nous même et pourtant j'en ai des choses à dire à ce sujet !
Du coup, on peut peut-être se donner un peu de temps (quelques mois ?) pour que tout le monde tente l'implémentation d'un petit langage de manière à se faire une idée de la chose, puis on pourra relancer le projet à partir de là. Qu'en pensez-vous ?
Je pense que c'est inutile, si le but est d'apprendre ensemble, pourquoi s'entraîner seul…
La communauté doit être capable de prendre une décision. Faisons un sondage pour choisir.
Un langage à la syntaxe simple comme Lisp ou Tcl/tk peut être un bon compromis. Après pour le paradigme un vote doit résoudre le soucis.
Petite suggestion qui ne mange pas de pain : avant de vous écharper sur des questions de syntaxe et de paradigme, essayez de vous mettre d'accord sur le type de problème que vous voulez gérer avec ce langage, fixez-vous un objectif clair et simple, et voyez ensuite ce qui vous parait approprié pour cela.
On fait comment pour compiler un langage fonctionnel vers LLVM-IR ?
J'ai balancé un lien sur IRC. Ce tutoriel est super long mais il explique beaucoup de choses évoquées dans ton message, notament les closures, le lambda calcul, la transformation d'un code fonctionnel en machine virtuelle (autre que LLVM), et finalement la compilation du langage (qui est un clone de Haskell) en LLVM-IR.
(Pour ceux qui en douteraient le post de @Dinosaure donne largement ce qu'il faut en infos).
Sinon, question stupide (mes cours de théories des langages, ça remonte …), un truc basique au possible type : Machine P-Code + Compilation d'un langage Pascal simplifié (juste des entiers et des tableaux statiques), ce serait pas un bon moyen de se simplifier la vie pour débuter ?
Alors certes, c'est pas le langage de la mort qui tue dont je rêve la nuit, mais au moins c'est de l'ordre du faisable.
Et sinon, pour prendre en main les notions de base de théorie des langages, ne pourrait-on pas travailler sur des projets de compilation moins ambitieux qu'un langage de programmation ? Je n'ai pas d'idée là tout de suite, mais le défi de Clem sur la calculatrice donne un aperçu. Se restreindre à des langages réguliers et jouer avec les automates me semble aussi intéressant.
Et puisque autant de personnes paraissent intéressées par le domaine, ne pourrait-on pas en profiter pour écrire du contenu ? On a des membres qui s'y connaissent, d'autres susceptibles de relire et commenter.
Je comprends pas votre discussion. Pourquoi est-ce que vous n'organisez pas plutôt un ensemble d'ateliers, de cours, de défis ou ce que vous voulez, où chacun implémente un langage respectant le paradigme/les idées qu'il préfère, dans le langage de son choix, avec la syntaxe de son choix, etc. bref, pourquoi est-ce que vous essayez de poser des contraintes aussi rigides ?
Concevoir et implémenter un langage de programmation c'est à la fois long et amusant, facile et fastidieux, il y a beaucoup de choses à lire et tout le monde ne sera pas intéressé par les mêmes aspects. Laissez les gens faire ce qu'ils ont envie de faire ? Faites plusieurs posts sur le forum avec le tag "zlang" ou ce que vous voulez, et éventuellement des petits articles comme celui de Dinosaure (dont j'espère qu'il sera retravaillé pour être posté ailleurs que sur ce topic) ?
Arrêtez de vous prendre la tête, en somme ?
La calculatrice est un exemple vraiment simpliste, mais j'aime bien l'idée. Si vous voulez toucher à une problématique de compilation sans entrer tout de suite dans le grand bain et sans bouée, vous pouvez aussi bosser sur un moteur d'expressions régulières. Le sujet a l'air débile comme ça, mais il cache un ensemble de problèmes et d'algorithmes étonnamment vaste et passionnant.
Puisque personne ne l'a encore proposé : pourquoi ne pas utiliser des regex pour faire le langage?1
Puisque j'ai déjà créé un compilateur pour un langage non trivialement compilable (un truc genre C avec de l'orienté objet) et que j'ai aussi expérimenté un certain nombre de sujets intéressantes (optimisations, Jit, LLVM), je pense que je peux avoir un avis intéressant.
Pour donner une idée du langage pour lequel le compilateur à été écrit :
- Langage impératif
- Typage statique fort avec quelques types primitifs : bool, char, int.
- Quelques type supplémentaires : classes, pointeurs, fonctions (utilisés en interne, non accessible depuis le langage).
- La plupart des opérations usuels : opérations arithmétiques
- Structures de données simples : fonctions, conditions, boucles.
- Include comme en C
- Output soit en LLVM (version texte), soit en un assembleur pour machine à pile (qui a aussi une heap séparé).
- La mémoire est géré par l'utilisateur : les classes sont forcément sur le tas et doivent toujours être détruites explicitement. Pour le reste, c'est comme en C.
- Possibilité de déclarer de l'assembleur inline pour la machine à pile ou une fonction externe à linker pour LLVM.
- Un mini librairie interne pour quelques fonctions basiques (strlen, strcopy, …).
- Quelques optimisations : propagation de constantes, suppression de code mort, simplification des expressions statiques (genre 5+4 ou 3*4).
- Gestion de l'héritage avec que des fonctions virtuelles (comme en Java).
Le compilateur à été écrit en Haskell avec Parsec pour le parsing. Tout le reste est fait main. En terme de connaissance, j'ai eu un cours sur la compilation où on nous a expliqué le principe des grammaires (sachant qu'avec Parsec, c'est même pas forcément nécessaire). Pour le reste, j'ai appris sur le tas.
En fait, il y a moyen de se débarrasser d'un bon nombre de problèmes en choisissant bien ses outils : Parsec permet d'aider énormément sur la syntaxe, LLVM permet de compiler en natif et de linker avec la libc en s'affranchissant de la plus grosse majorité des problèmes potentiels (affectation des registres, connaissance poussé de l'assembleur, syscall) et générer une version texte de LLVM-IR permet de limiter les connaissances nécessaires au stricte minimum. D'autres choix permettent d'éviter certains problèmes : l'inférence de type, la surcharge de fonction ou d'opérateur, les cast implicites, c'est cool, mais ça risque d'ajouter plus de difficulté que nécessaire.
Le plus gros problème en fait a été d'ajouter des features au fur et à mesure tout en conservant un code assez propre. Même en essayant au début de restreindre au minimum la représentation interne, il arrive qu'une feature (POO, éléments spécifiques à un backend, #include) nécessite de modifier certaines choses assez profond en interne, ce qui peut avoir un coût assez énorme. Mais même si ça peut nécessiter beaucoup de temps et de modifications, il ne faut pas hésiter à changer le cœur du compilateur si c'est nécessaire plutôt que de commencer à essayer de régler certains problèmes à coup de scotch.
Je suis d'accord que c'est bien de pas tout réinventer, mais il faut rester raisonnable. Je préfère encore qu'on fasse un langage interprété simple plutôt qu'on utilise LLVM qui est un super gros bidule. Mais ça on en est même pas encore là. Ça sert à rien de décider quels outils on va utiliser si on a même pas défini ce qu'on veut comme mini-langage. Tant qu'on a pas de spécification quelque part avec les lexèmes et l'AST et la sémantique on se fout du reste.
Moi je vous ai suggéré un Lisp-like et proposé un AST qui peut être bien amélioré parce que c'est le tout premier interpréteur que j'ai jamais écrit et que c'était mon deuxième projet OCaml, Carnufex a posté un AST sorti du compilo Haskell, d'autres parlaient de langages impératifs, il y a Dinoscheme pour s'inspirer, etc. À un moment il faudra choisir dans quelle direction aller et je sais pas comment organiser un tel choix. Je sais même pas si c'est possible de gérer toutes les divergences d'opinion des gens.
Avant même de sortir une spécification complète du langage, ça serait judicieux d'établir juste son idée de base, ultrasimple, avec un AST pas fini mais avec juste de quoi faire une espèce de Hello World. Vous voulez faire comment, un post par proposition et ça vote au +/-1 ?
- Near,
Pourquoi ne pas juste créer un petit langage de script par exemple ?
Comme ça on ne se préoccupe pas des soucis de compilation et ça nous enlève pas mal de "blocage".
Si le but est d'apprendre je propose de faire un langage avec un lexer et un parser (créer de nous-même ou en utilisant une bibliothèque déjà existante) afin de se concentrer sur la programmation de la syntaxe pour que chacun d'entre nous apprennes à implémenter des fonctionnalité différente (comme les structure if/else/while/etc) afin que le langage soit le plus facilement modulable. (Mais avec un peu de difficulté sinon ce serait trop facile )
PS: Comme Berdes l'a fait, je vous met aussi le lien d'un langage de script nommé Kasual que j'ai créer en python 3 (https://github.com/Skelord/Kasual)
- olzd,
Sauf que le lexing/parsing c'est la partie la plus chiante de l'implémentation d'un langage; ce serait dommage de se priver des outils existants…
Si vous cherchez à faire le truc le plus simple possible, mais utilisable, je dirais qu'un language type Lisp interprété avec un type checking au runtime, ça doit pas être bien difficile. Ça a l'avantage de permettre de découper les tâches : pour avoir un truc fonctionnel il "suffit" d'un parser et d'un interpréteur. Il est ensuite possible de faire l'analyse de type avant l'exécution, compiler le langage, y ajouter des fonctionnalités, y ajouter une version avec une syntaxe plus commune, etc. Le tout plus ou moins dans l'ordre que vous voulez, suivant ce qui semble le plus intéressant ou le plus facile à faire.
- Near,
Eh bien personnellement j'aime bien yacc et lex, il existe sous de nombreux langages diffèrent même si certain laisse à désirer (ply)
Ce serait pas mal avec un petit système de nœd fait maison facile à assimiler mais tout d'abord il faut créer la syntaxe globale et choisir le/les langages de programmation(s) avec lesquels un maximum de personnes pourront participer
- Near,
En vérité il n'y a pas beaucoup de reproche à faire dessus bien que j'ai des souvenirs que l'on ne pouvait pas utiliser le parser (yacc) de manière indépendante au lexer, en gros on est obligé d'utiliser le lexer par défaut et on ne peux donc pas implémenter notre propre lexer (du moins j'avais réussis mais en modifiant le code source de ply ce qui n'est pas le but de cet atelier)
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