• [^] # Re: Représentations intermédiaires du compilateur OCaml

    Posté par . En réponse au journal Malfunction: réutiliser la représentation intermédiaire du compilateur OCaml. Évalué à 3.

    De plus, j'ai l'impression que du confonds la syntaxe de malfunction et la syntaxe de Lambda. Qui sont apparemment deux langages différents, par exemple quand tu parles de [...] C'est à propos de Malfunction, et non pas de Lambda. Or, la question porte justement sur le fait de remplacer Lambda par un Scheme.

    On a dû mal se comprendre. Malfunction c'est en gros une version simplifiée (et spécifiée) de Lambda, un langage à une distance minimale qui permet d'être clair et facilement interprétable et quand même se traduire de façon très transparente vers Lambda. Quand tu proposes d'utiliser un Scheme "à la place", je comprends "à la place de Malfunction", et pas "à la place de Lambda", puisque (1) Lambda lui-même n'est pas proposé comme cible directe pour les autres langages et (2) traduire Malfunction tel qu'il est vers Lisp/Scheme serait difficile voire impossible (sans perte d'efficacité) vu l'impedance mismatch entre les représentations. Si tu veux un compilo qui vise une implem. Lisp/Scheme, il faut produire du Lisp/Scheme (ou une de leurs représentations internes), pas du Lambda-de-OCaml-simplifié.

    Ou alors tu demandes peut-être si le compilateur OCaml pourrait compiler vers (la représentation intermédiaire d'un compilateur) Lisp ou Scheme, mais là c'est une question encore différente qui n'a pas vraiment de sens—en fait les premiers Caml étaient implémentés de cette façon là, et je crois qu'il y a eu un frontend Bigloo ou Stalin pour Caml, mais aujourd'hui les langages, sémantiques et attentes de domaine optimisé sont trop différentes je pense.

    [Sur le fait que Lambda gère les types sommes] Je veux bien te croire sur parole (étant donné qu'il n'existe pas de spécification du langage), [...]

    Regarde par exemple la partie lambda_switch de l'AST Lambda, qui définit une construction de switch avec une famille de cas pour gérer les constructeurs constants (représentés comme des entiers) et les constructeurs à paramètres (boxés sur le tas, donc avec un pointeur en tête et un tag de constructeur quand on suit le pointeur).

    piper un AST texte sous-entends que c'est une phase « alpha », prototype, enfin, quelque chose de pas propre. Et quand on voudra le faire proprement, [...] on repose sur un truc instable, génial.

    L'auteur de compilateur continue à viser la représentation Malfunction, qui est stable. C'est s'il veut appeler le compilateur OCaml directement depuis son frontend qu'il doit utiliser l'API du compilo qui n'est pas stable. Mais bon LLVM n'offre pas de stabilité entre les versions non plus et pourtant plein de compilateurs l'utilisent—souvent à raison.

    Par ailleurs c'est classique dans un compilateur de produire une représentation intermédiaire dans un fichier et d'appeler derrière un outil externe—au lieu de tout avoir dans un même processus. Chicken Scheme lui-même produit du C et appelle un compilo C derrière. Beaucoup de compilateurs natifs produisent une représentation textuelle de l'assembleur généré et appellent l'assembleur système derrière. Pareil pour le linker, tu ne recodes pas, tu appelles un programme externe. Ce n'est pas fondamentalement "alpha" et ça marche bien.

    Sur les macros: que tu définisses un langage propre (Malfunction) ou un ensemble de macros par dessus un langage plus simple, ça ne change pas grand chose du point de vue de l'utilisateur, c'est-à-dire l'implémenteur d'Idris, Eff ou Links. Dans tout les cas il faut produire cette représentation intermédiaire.

    On ne peut pas le faire en utilisant un programme C intermédiaire ?

    Ben ça dépend de comment les deux langages sont compilés et si les représentations sont compatibles. Par exemple si les types algébriques sont représentés différemment, il faut traduire d'une représentation vers l'autre, donc tu as coût important quand tu transfères des données (alors qu'avec une représentation partagée, rien à faire). Si tu as deux GCs avec des attentes incompatibles, encore une fois c'est la prise de tête et une coopération moins efficace.

    Par exemple Coq utilise pas mal le fait qu'il compile vers OCaml pour écrire des programmes mixtes. (Dans Compcert par exemple, le gros du compilo est du Coq, mais il y a des parties en OCaml et c'est bien pratique (et l'efficacité est importante).