Beaucoup de questions sont posées ici sur les outils de langage interprétés vs compilés. Je me demande si la distinction a vraiment un sens. (En fait, les questions portent généralement sur les langues, mais elles pensent vraiment aux implémentations les plus populaires de ces langues).
Aujourd'hui, pratiquement aucune mise en œuvre n'est strictement interprétée. c'est-à-dire que pratiquement personne n'analyse et exécute le code une ligne à la fois. De plus, l'implémentation qui compile en code machine devient également moins courante. De plus en plus, les compilateurs ciblent une sorte de machine virtuelle.
En fait, la plupart des mises en œuvre convergent vers la même stratégie de base. Le compilateur produit un bytecode qui est interprété ou compilé en code natif via un JIT. C'est vraiment un mélange des idées traditionnelles de compilation et d'interprétation.
Je pose donc la question suivante: existe-t-il une distinction utile entre les implémentations interprétées et l'implémentation compilée de nos jours?
la source
P-code
avait été introduit en 1966 pour la première fois. IBM Aix existe depuis 1986.Réponses:
Il est important de se rappeler que l'interprétation et la compilation ne sont pas seulement des alternatives l'une à l'autre. En fin de compte, tout programme que vous écrivez (y compris un programme compilé en code machine) est interprété. Interpréter le code signifie simplement prendre un ensemble d'instructions et renvoyer une réponse.
Compiler, d'autre part, signifie convertir un programme dans une langue vers une autre langue. Habituellement, on suppose que lors de la compilation, le code est compilé dans un langage de "niveau inférieur" (par exemple, code machine, une sorte de bytecode VM, etc.). Ce code compilé est toujours interprété plus tard.
En ce qui concerne votre question de savoir s'il existe une distinction utile entre les langues interprétées et compilées, mon opinion personnelle est que tout le monde devrait avoir une compréhension de base de ce qui se passe avec le code qu'ils écrivent pendant l'interprétation. Donc, si leur code est compilé en JIT, ou mis en cache par bytecode, etc., le programmeur devrait au moins avoir une compréhension de base de ce que cela signifie.
la source
La distinction est profondément significative car les langages compilés restreignent la sémantique d'une manière que les langages interprétés ne font pas nécessairement. Certaines techniques d'interprétation sont très difficiles (pratiquement impossibles) à compiler.
Le code interprété peut faire des choses comme générer du code au moment de l'exécution et donner à ce code une visibilité sur les liaisons lexicales d'une étendue existante. Voilà un exemple. Un autre est que les interprètes peuvent être étendus avec du code interprété qui peut contrôler la façon dont le code est évalué. C'est la base des anciens "fexprs" de Lisp: des fonctions qui sont appelées avec des arguments non évalués et qui décident quoi en faire (avoir un accès complet à l'environnement nécessaire pour parcourir le code et évaluer les variables, etc.). Dans les langages compilés, vous ne pouvez pas vraiment utiliser cette technique; vous utilisez des macros à la place: des fonctions qui sont appelées au moment de la compilation avec des arguments non évalués, et traduisez le code plutôt que d'interpréter.
Certaines implémentations de langage sont construites autour de ces techniques; leurs auteurs rejettent la compilation comme étant un objectif important et adoptent plutôt ce type de flexibilité.
L'interprétation sera toujours utile comme technique d'amorçage d'un compilateur. Pour un exemple concret, regardez CLISP (une implémentation populaire de Common Lisp). CLISP a un compilateur qui est écrit en lui-même. Lorsque vous générez CLISP, ce compilateur est interprété au cours des premières étapes de génération. Il est utilisé pour se compiler, puis une fois compilé, la compilation se fait à l'aide du compilateur compilé.
Sans noyau d'interpréteur, vous auriez besoin de démarrer avec du Lisp existant, comme le fait SBCL.
Avec l'interprétation, vous pouvez développer un langage à partir de zéro, en commençant par le langage d'assemblage. Développez les E / S de base et les routines de base, puis écrivez un eval, toujours un langage machine. Une fois que vous avez évalué, écrivez dans la langue de haut niveau; le noyau du code machine effectue l'évaluation. Utilisez cette fonction pour étendre la bibliothèque avec de nombreuses autres routines et écrire également un compilateur. Utilisez le compilateur pour compiler ces routines et le compilateur lui-même.
Interprétation: un tremplin important dans le chemin menant à la compilation!
la source
En fait, de nombreuses implémentations de langues sont toujours strictement interprétées, vous ne les connaissez peut-être pas. Pour n'en nommer que quelques-uns: les langages shell UNIX, les shells Windows cmd et PowerScript, Perl, awk, sed, MATLAB, Mathematica et ainsi de suite.
la source
Je pense: absolument oui .
Vraiment, C ++ vise à porter au domaine du compilateur un concept de haut niveau qui est généralement remis aux interprètes, mais il reste du côté minoritaire ...
la source
Distinction utile: les programmes interprétés peuvent se modifier eux-mêmes en ajoutant ou en modifiant des fonctions lors de l'exécution.
la source