web-dev-qa-db-fra.com

Interprété vs compilé: une distinction utile?

Beaucoup de questions sont posées ici à propos de l'interprétation des outils linguistiques compilés par VS. Je me demande si la distinction a effectivement un sens. (En réalité, les questions sont généralement des langues, mais ils pensent vraiment aux implémentations les plus populaires de ces langues).

Aujourd'hui, presque aucune mise en œuvre n'est strictement interprétée. C'est-à-dire que, à peu près, personne ne traite et exécute le code une ligne à la fois. De plus, la mise en œuvre qui compilait au code de la machine devient également moins courante. Les compilateurs ciblent de plus en plus une sorte de machine virtuelle.

En fait, la plupart des mises en œuvre convergent sur la même stratégie de base. Le compilateur produit ByTecode qui est interprété ou compilé au code natif via une JIT. C'est vraiment un mélange des idées traditionnelles de compilation et d'interprétation.

Ainsi, je demande: existe-t-il une distinction utile entre les implémentations interprétées et la mise en œuvre compilée ces jours-ci?

31
Winston Ewert

Il est important de se rappeler que l'interprétation et la compilation ne sont pas seulement des alternatives les unes des autres. En fin de compte, tout programme que vous écrivez (y compris une compilée au code de la machine) est interprété. L'interprétation du code signifie simplement prendre un ensemble d'instructions et renvoyer une réponse.

La compilation, d'autre part, signifie convertir un programme dans une langue à une autre langue. Habituellement, il est supposé que lorsque la compilation a lieu, le code est compilé dans une langue de "niveau inférieur" (par exemple, le code de machine, une sorte de type VM bytecode, 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 au code qu'ils écrivent pendant l'interprétation. Donc, si leur code est en train d'être compilé, ou en mises en cache de bytecode, etc., le programmeur doit au moins avoir une compréhension de base de ce que cela signifie.

25
Zach Smith

La distinction est profondément significative car les langues compilées limitent la sémantique de manière à ce que les langues interprétées ne soient pas nécessairement. Certaines techniques d'interprétation sont très difficiles (pratiquement impossibles) de compiler.

Le code interprété peut faire des choses comme générer du code au moment de l'exécution et donner la visibilité de ce code dans des liaisons lexicales d'une portée existante. C'est un exemple. Un autre est que les interprètes peuvent être étendus avec un code interprété pouvant contrôler comment le code est évalué. C'est la base de l'ancien LISP "FEXPRS": les fonctions qui sont appelées avec des arguments inévalués et décident de quoi faire avec eux (ayant un accès complet à l'environnement nécessaire pour parcourir le code et évaluer les variables, etc.). Dans les langues compilées, vous ne pouvez pas vraiment utiliser cette technique; Vous utilisez des macros à la place: les fonctions qui sont appelées au moment de la compilation avec des arguments inévalués et traduisent le code plutôt que d'interpréter.

Certaines implémentations linguistiques sont construites autour de ces techniques; Leurs auteurs rejetent la compilation comme un objectif important et plutôt embrasser ce type de flexibilité.

L'interprétation sera toujours utile en tant que technique pour bootstrapping un compilateur. Pour un exemple concret, consultez Clisp (une implémentation populaire de LISP commun). Clisp a un compilateur qui est écrit en soi. Lorsque vous construisez CLISP, ce compilateur est interprété lors des étapes du bâtiment précoce. Il est utilisé pour se compiler, puis une fois compilé, la compilation est ensuite effectuée à l'aide du compilateur compilé.

Sans noyau d'interprétation, vous auriez besoin de bootstrap avec quelques LISP existants, comme SBCL.

Avec une interprétation, vous pouvez développer une langue d'une éraflure absolue, en commençant par la langue d'assemblage. Développez les routines d'E/S et de base de base, puis écrivez une langue eval, toujours de la machine. Une fois que vous avez évalué, écrivez dans la langue de haut niveau; Le noyau de code de la machine effectue l'évaluation. Utilisez cette installation pour étendre la bibliothèque avec de nombreuses autres routines et écrire un compilateur également. Utilisez le compilateur pour compiler ces routines et le compilateur lui-même.

Interprétation: une étape importante dans le chemin menant à la compilation!

12
Kaz

En fait, beaucoup d'implémentations de langues sont toujours strictement interprétées, vous ne pouvez pas en prendre au courant. Pour nommer quelques-uns: les langues de coquille Unix, les coquilles de Windows CMD et Powerscript, Perl, Awk, SED, Matlab, Mathematica, etc.

1
Charles E. Grant

Je pense: absolument oui.

En fait, la plupart de la mise en œuvre convergent sur la même stratégie de base

Vraiment, C++ vise à porter au domaine du compilateur Quelque concept de haut niveau qui est généralement remis aux interprètes, mais il reste du côté minoritaire ...

1
CapelliC

Il est utile de se rappeler que "compilé" n'est pas seulement le nom d'une catégorie de programmes, mais est également un verbe (en particulier le participe passé de "compiler"). En d'autres termes, tout programme entrant dans la catégorie "compilée" devait avoir été transmis via une compilation événement ou processus. Ceci est une différence qualitative par rapport aux programmes qui ne sont pas compilés; Ce n'est pas gris du tout.

Un processus de compilation comprend plus que la traduction de code source au code d'objet. Il comprend également plusieurs caractéristiques propres à la compilation:

  1. Directives, conditionnels et variables de compilation ("prétraitement")
  2. Validation du temps de compilation, par exemple Syntaxe et type vérification
  3. Erreurs de la compilation
  4. Reliure précoce
  5. Liaison statique
  6. Certaines optimisations, telles que des appels de relevés de chaîne et de queue

Cela conduit à certaines différences clés, par exemple, un programme compilé doit contenir un code source valide (mais pas nécessairement correct). En revanche, un programme interprété peut contenir une source qui n'est pas valide. Il est possible qu'un programme JavaScript fonctionne simplement bien jusqu'à ce qu'elle rencontre une ligne de code non valide, à laquelle il se sort simplement d'une halle ou d'une erreur.

Je suppose qu'il y ait quelque chose d'une zone grise en matière de code JIT-compilé, qui, à certains égards, est traité comme un code interprété - code source non valide, par exemple, peut ne pas causer de problème tant que la compilation JIT se produit. Cependant, une fois la compilation JIT terminée, vous pouvez être assuré que le code est maintenant valide.

Cette distinction est-elle "utile?" Je suppose que c'est une question d'opinion. Cependant, je n'engagerais probablement pas un ingénieur logiciel qui ne comprenait pas la différence.

1
John Wu

Distinction utile: les programmes interprétés peuvent se modifier en ajoutant ou en modifiant des fonctions au moment de l'exécution.

0
Diego Pacheco

Je pense que la distinction est devenue très gris. Je faisais des recherches sur la façon d'avoir Java appel Matlab, trébuché sur le concept que Java est compilé en Matlab est, bien, compilé à un niveau inférieur ces jours-ci. Provenant d'un arrière-plan de conception de circuit numérique, je sais que peuvent être représentés par une séquence de code correspondant à la commande logique d'enregistrer même des opérations au niveau des transitions de la machine d'état dans l'état. En effet, le code décrivant exactement comment et quand ces " événements " se produisent à un niveau matériel peut regarder remarquablement comme code source L3G (quand décrite dans Verilog, VHDL, SystemC). Est-ce que nous appelons ces vues de haut niveau des opérations de bas niveau " code source " pour être compilé? Que faire si les opérations sont précisées en détail afin qu'il n'y ait pas de liberté pour le compilateur de prendre une décision sur la logique booléenne finale? Ensuite, il est juste question de l'étiquetage des matériels, des états et des E/S avec des noms de créateurs convivial - est que le code source encore à compiler? Même visualisation zéros et de uns dans un éditeur est une abstraction, comme les états binaires réels sont le résultat de configurations de grille de transistor avec certains niveaux de charge et des tensions en certains noeuds. Le long de ces lignes, doit-on considérer la sélection de cellules logiques, la mise en page, et l'interconnexion de routage en degrés de liberté qui qualifient la cartographie de description codée au matériel et son fonctionnement comme " compilation "?

Malgré le flou, cependant, je pense toujours de Matlab comme ressemblant Interpretation d', car il dispose d'une ligne de commande interactive. Je peux naviguer et manipuler des objets de données entre les états de ligne de commande. VBA est compilé, mais il a la " fenêtre immédiate " dans laquelle je peux faire la même chose. Les débogueurs C de me donner le même genre d'environnement, bien que je ne l'ai pas utilisé un L3G depuis des décennies, et la fonctionnalité était de retour assez maladroit dans la journée. Là encore, Java est " compilé " et une recherche sur le Web montre qu'il a aussi une ligne de commande interactive pour apprendre Java (que je ne sais pas).

Tout cela pour dire que même si nous tirons de retour des détails techniques et examiner la question que dans la perspective de la boîte noire de la façon dont il se sent et ce que l'on peut faire à la console, il est encore assez floue.

0
user2153235