Des exemples de quand nous utiliserons un langage interprété sur un langage compilé?

11

Je comprends les différences entre les langues interprétées et compilées, mais si quelqu'un pouvait fournir des exemples de situations où l'on est susceptible d'utiliser des langues interprétées sur des langues compilées, ainsi que des situations où l'on est susceptible d'utiliser des langues compilées sur des langues interprétées, ce serait être vraiment utile.

KL
la source

Réponses:

11

Il n'y a (à ma connaissance) rien de tel qu'une «langue» interprétée ou une «langue» compilée.

Les langages spécifient la syntaxe et la signification des mots clés du code, des constructions de flux et diverses autres choses, mais je ne connais aucun langage qui spécifie s'il doit être compilé ou interprété dans la spécification de langage.

Maintenant, si votre question est de savoir quand vous utilisez un compilateur de langue par rapport à un interprète de langue, cela se résume vraiment aux avantages / inconvénients du compilateur par rapport à l'interpréteur et à l'objectif du projet.

Par exemple, vous pouvez utiliser le compilateur JRuby pour une intégration plus facile avec les bibliothèques java au lieu de l'interpréteur ruby ​​MRI. Il y a probablement aussi des raisons d'utiliser l'interpréteur de rubis IRM sur JRuby, je ne connais pas bien la langue et je ne peux pas en parler.

Avantages des interprètes:

  • Aucune compilation signifie que le temps entre la modification du code et le test de l'application peut être réduit
  • Pas besoin de générer des binaires pour plusieurs architectures car l'interpréteur gérera l'abstraction de l'architecture (même si vous devrez peut- être encore vous soucier des scripts qui gèrent correctement les tailles entières, mais pas de la distribution binaire)

Avantages des compilateurs:

  • Le code natif compilé n'a pas la surcharge d'un interprète et est donc généralement plus efficace dans le temps et l'espace
  • L'interopérabilité est généralement meilleure, le seul moyen d'interopérabilité in-proc avec des scripts est via un interpréteur plutôt qu'un FFI standard
  • Capacité à prendre en charge les architectures pour lesquelles l'interpréteur n'a pas été compilé (comme les systèmes embarqués)

Cependant, je parierais que dans 90% des cas, cela ressemble à ceci: je veux écrire ce logiciel en blub parce que je le connais bien et qu'il devrait faire du bon travail. J'utiliserai l'interpréteur blub (ou le compilateur) car c'est la méthode canonique généralement acceptée pour écrire des logiciels dans blub.

Donc TL; DR est fondamentalement, une comparaison au cas par cas des interprètes vs les compilateurs pour votre cas d'utilisation particulier.

Aussi, FFI: Foreign Function Interface, en d'autres termes interface pour interopérer avec d'autres langues. Plus de lecture sur wikipedia

Jimmy Hoffa
la source
2
À ma connaissance, certains langages de script pour OS tels que ksh pour UNIX ne peuvent pas être compilés.
NoChance
@delnan, mon point de vue ne peut pas être compilé via un logiciel commercial ou gratuit que je connaisse, pas qu'il ne puisse pas être compilé pour des raisons techniques.
NoChance
3
@EmmadKareem Il n'y a rien de tel que "ne peut pas être compilé". Vous écrivez un programme qui lit un programme en langage Li et génère un programme équivalent en langage La. C'est un compilateur un compilateur. J'hésite à invoquer l'argument d'exhaustivité turing car c'est un hareng rouge dans la pratique, mais chaque programme se transforme finalement en une séquence d'instructions de code machine. Si tout le reste échoue, déroulez la boucle d'interpréteur (et simplifiez le code résultant pour supprimer les parties dont vous n'avez plus besoin). Si l'interpréteur est écrit dans une langue sans interprètes, répétez jusqu'à ce que vous frappiez quelque chose avec un compilateur.
1
(J'ai caviardé mon commentaire pour mieux le formuler, mais apparemment j'ai agi trop tard.) @EmmadKareem Oui, évidemment, certains langages n'ont jamais été implémentés via un compilateur. Mais je ne vois pas en quoi cela est pertinent. C'est toujours possible et faisable de le faire, et cela peut être fait à tout moment avec un certain effort. C'est une conséquence du point principal, qui est qu'un langage n'est ni intrinsèquement compilé ni interprété, et peut être implémenté dans les deux sens. Et d'une myriade d'autres façons (enfin, sans doute des variantes et des remixes mineurs), soit dit en passant.
2
@EmmadKareem si vous le souhaitez, vous pouvez prendre la spécification du langage ksh et écrire un compilateur qui le lira et générera un binaire natif. La langue en cours de compilation ou d'interprétation n'est pas dans la définition d'une langue est mon point ici.
Jimmy Hoffa
8

Un point important ici est que de nombreuses implémentations de langage font en fait une sorte d'hybride des deux. De nombreuses langues couramment utilisées aujourd'hui fonctionnent en compilant un programme dans un format intermédiaire tel que le bytecode, puis en l'exécutant dans un interpréteur. C'est ainsi que Java, C #, Python, Ruby et Lua sont généralement implémentés. En fait, c'est sans doute ainsi que la plupart des langues utilisées aujourd'hui sont implémentées. Ainsi, le fait est que le langage interprète et compile aujourd'hui son code. Certains de ces langages ont un compilateur JIT supplémentaire pour convertir le bytecode en code natif pour exécution.

À mon avis, nous devrions cesser de parler des langages interprétés et compilés car ils ne sont plus des catégories utiles pour distinguer les complexités des implémentations de langage d'aujourd'hui.

Lorsque vous posez des questions sur les mérites des langues interprétées et compilées, vous voulez probablement dire autre chose. Vous vous demandez peut-être le mérite du typage statique / dynamique, les avantages de la distribution d'exécutables natifs, les avantages relatifs de la compilation JIT et AOT. Ce sont tous des problèmes qui sont confondus avec l'interprétation / la compilation, mais ce sont des problèmes différents.

Winston Ewert
la source
2

Tout d'abord, un langage de programmation peut être à la fois ininterprété et compilé. L'interprétation et la compilation ne sont que des méthodes pour générer du code exécutable à partir du code source. Avec un interprète, le code source est lu et interprété par un interprète qui exécute ensuite le code tel qu'il l'interprète. Un compilateur, d'autre part, lit le code source et génère un fichier binaire exécutable à partir du code source - afin que le programme puisse être exécuté en tant que processus séparé indépendamment.

Maintenant, avant que quiconque ne se demande ... Oui, C / C ++ / C # / Java peut être interprété, et oui, les scripts JavaScript et Bash peuvent être compilés. Qu'il y ait des interprètes ou des compilateurs qui travaillent pour ces langues est une autre question.

Maintenant, pour répondre à la question, nous allons utiliser le "langage interprété" plutôt que le "langage compilé". La question elle-même est quelque peu confuse, mais je suppose que cela signifie quand préférer l'interprétation à la compilation. L'un des inconvénients de la compilation est qu'elle génère des frais généraux en raison du processus de compilation - le code source doit être compilé en code machine exécutable, il n'est donc pas adapté aux tâches qui nécessitent un délai minimal lors de l'appel du code source pour exécuter un programme. D'un autre côté, le code source compilé est presque toujours plus rapide que le code source interprété équivalent en raison de la surcharge causée par l'interprétation du code. Les interprètes d'autre part peuvent invoquer et exécuter le code source avec très peu de frais d'appel, mais au détriment des performances d'exécution.

En fin de compte, il est presque impossible de mentionner des cas d'utilisation définis quand préférer l'un après l'autre, mais par exemple un cas (à mon sens très irréaliste) serait lorsque le code source du programme change dynamiquement entre les invocations de programme et la surcharge de compilation est trop élevé pour qu'il soit un choix viable. Dans ce cas, l'interprétation du code source au lieu de la compilation serait probablement souhaitable.

Cependant, il y a quelque chose qui peut être considéré comme un exemple réel: le code source hidnig lors du déploiement. Avec nativementcode compilé le développeur déploie le code macine exécutable du programme et des données. Avec du code interprété, le code source lui-même doit être déployé, qui peut ensuite être inspecté et rétroconçu avec beaucoup moins d'efforts que ce qu'il en est pour la rétro-ingénierie du code machine natif. Une exception à cela est les langages comme C # et Java qui se compilent en langage / bytecode immédiat (MSIL pour C # et Java bytecode pour Java) qui sont ensuite déployés et compilés "juste à temps" au moment de l'exécution, un peu comme un interprète. Cependant, il existe des soi-disant décompilateurs pour MSIL et Java Bytecode qui peuvent reconstruire le code source d'origine avec une précision relativement bonne et, en tant que tels, la rétro-ingénierie de tels produits est beaucoup plus triviale que les produits de rétro-ingénierie déployés dans du code machine natif.

zxcdw
la source
1
Vous soulevez de bons points, mais étant le pédant que je suis, je conteste certaines formulations (toutes deux faisant référence au troisième paragraphe): 1. Un interprète ne compile pas. 2. Il est concevable (bien que ces conditions soient rares) qu'un mauvais compilateur non optimisant soit battu par un interpréteur hautement optimisé (en particulier basé sur le bytecode). Cela va doublement si vous comptez les compilateurs JIT sous les interprètes (ce que je préfère ne pas faire, mais certaines personnes le font).
@delnan Peut-être que c'est mal formulé, je ne suis pas un locuteur natif anglais. Cependant, pour autant que je sache, le troisième paragraphe n'implique pas qu'un interprète compile. Pour le deuxième point, j'ai insisté sur le mot équivalent à l'accent sur la similitude du code compilé et interprété pour exclure les cas de mauvais compilateur par rapport à un interprète performant, peut-être que je n'étais pas clair avec lui, mais je ne le vois pas raisonnable de se concentrer sur l'explication de ces cas extrêmes car cela ne contribue en rien à ce qui est fait entre les différences d'exécution du code source en le compilant ou en l'interprétant
zxcdw
Désolé, peu importe le premier point, j'ai mal lu quelque chose. Mea culpa. Quant au deuxième point: j'ai pris "équivalent" pour faire référence au code qui est interprété ou compilé (et comparer un compilateur et un interpréteur n'a pas beaucoup de sens, car ils font des choses fondamentalement différentes). Je ne pense pas que l'on devrait perdre du temps à détailler des cas bizarres comme mon exemple, mais je préférerais laisser tomber le "toujours" en faveur d'un libellé qui explique pourquoi il peut être plus rapide en premier lieu: pas de frais généraux d'interprète [qui devraient être IMHO défini], et possibilité d'effectuer des optimisations avant l'exécution.
1

Je peux penser aux scénarios suivants lorsque vous utiliseriez un langage interprété :

  • Là où aucun compilateur n'existe, comme les scripts shell Linux / Unix .
  • Scripts rapides et sales qui résolvent un petit problème
  • Langages qui facilitent l'écriture de pages HTML dynamiques et sont généralement interprétés comme JSP (Tomcat le compile en un servler previos à exécuter), PHP, ASP etc.

Je peux penser aux scénarios suivants lorsque vous souhaitez compiler votre code:

  • Vous devez distribuer des fichiers binaires car votre application est de source fermée et vous ne voulez pas donner votre code source.
  • Vitesse, comme les systèmes embarqués et similaires.
  • Vous avez besoin d'un niveau de sécurité de type de code que seul un compilateur avec un langage strictement typé peut vous donner. Les compilateurs exposent les fautes de frappe dans tous les coins et recoins de votre code source, tandis que dans les programmes interprétés, les fautes de frappe peuvent passer inaperçues dans le code de production.
  • Grands systèmes complexes: vous ne pouvez pas imaginer un système d'exploitation ou une combinaison de bureau autrement que des binaires compilés.
  • Vous voulez éliminer tous les petits frais généraux et avez besoin d'une bonne communication avec les extraits d'assembleur (difficile avec tout type d'exécution, en particulier avec un interprète) (ce point provoqué par un commentaire @delnam)
Tulains Córdova
la source
3
Un interprète de langue rend la langue non moins fortement typée. Haskell est extrêmement fortement typé et vous pouvez utiliser GHCI pour l'interpréter efficacement. Le typage fort / faible est un aspect d'une langue, pas un aspect d'un compilateur ou d'un interprète.
Jimmy Hoffa
1
-1 Sur les avantages de la compilation: (1) La compilation du code ne protège pas contre le reverse engineering, il le rend juste un peu plus difficile. (2) La compilation (suppression des frais généraux de l'interpréteur, optimisation automatisée du code d'application) n'est qu'une source de performances et est dépassée par les optimisations à grande échelle faites à la main par un expert humain. (3) La vérification de type, bien que généralement associée à la compilation, en est indépendante. Un vérificateur de type est une passe d'analyse statique; cela peut se produire sans émettre de code et avant d'interpréter le code. (4) Semble assez faux. Vous "ne pouvez pas imaginer" cela? Pourquoi? Comment est-ce nécessaire?
1
D'autres langues interprétées existent chaque fois qu'il y a un interprète dans un autre programme. Chaque fois que l'on utilise le modèle d'interpréteur , il y a un langage interprété d'une certaine complexité.
3
les "scripts" ne sont pas nécessairement interprétés. De nombreux langages de "scripting" sont compilés en bytecode pour une machine virtuelle qui est ensuite exécutée (voir lua, perl, python, ruby). Il n'y a pas de réelle différence entre cela et java autre que lorsque la compilation a lieu.
3
+1, je pense que c'est le genre de réponse que le PO recherchait vraiment, et bien que les points ne soient pas vrais à 100% comme indiqué, il y en a au moins 95% pour des considérations pratiques.
Doc Brown
1

En fin de compte, le grand compromis est entre la productivité (combien de lignes de code devez-vous écrire) et les performances (à quelle vitesse votre programme s'exécutera-t-il).

Parce que les langages interprétés lorsqu'ils sont transformés en informations CPU ont plus d'informations, ils peuvent s'appuyer sur la réflexion et le typage dynamique qui augmentent considérablement la productivité . Un autre avantage des langages interprétés est qu'ils sont indépendants de la plateforme tant qu'il y a un interprète pour la plateforme.

Parce que le CPU ne doit pas transformer le code de langue en code machine et exécuter le code en même temps, comme dans le cas interprété, les langues compilées produisent des programmes plus rapides. De plus, un système construit dans un langage compilé est plus sécurisé car il peut détecter des problèmes au moment de la compilation, ce qui signifie essentiellement que vous voyez une erreur lorsque vous la tapez (avec des IDE modernes) au lieu de la voir uniquement lorsque vous exécutez réellement le programme (bien sûr , cela ne corrige pas les erreurs logiques).

Sachant cela, les langages interprétés conviennent pour:

  1. Développement productif: développement web rapide (PHP, Javascript) ou pour le prototypage.
  2. Multiplateforme; par exemple, JavaScript est pris en charge dans tous les navigateurs (y compris les navigateurs mobiles).

Et les langues compilées conviennent lorsque:

  1. Les performances sont critiques (systèmes d'exploitation) ou les ressources sont rares (microcontrôleurs).
  2. Les systèmes à construire sont complexes; lors de la construction de grands systèmes (systèmes d'entreprise), les langages compilés sont essentiels pour gérer de nombreux bogues possibles pouvant apparaître dans les langages interprétés; les programmes complexes nécessitent également de nombreuses ressources et la balance tend également vers les langues compilées.
m3th0dman
la source
-1 parce que vous indiquez que toutes les langues interprétées sont typées dynamiquement et que toutes les langues compilées sont typées statiquement, ce qui est complètement faux.
Daniel Pryden
@DanielPryden Ce doit donc être une pure coïncidence, le fait que presque tous les langages interprétés sont typés dynamiquement et ceux compilés statiquement? Est-ce une coïncidence si le modèle de type dynamique convient aux langages interprétés?
m3th0dman
Pour diverses raisons, il existe une corrélation, mais ce n'est pas une exigence. Cela a en fait été demandé sur StackOverflow: Pourquoi les interprétés sont-ils pour la plupart typés duck alors que les compilations ont un typage fort?
Daniel Pryden
1
Erlang est compilé et typé dynamiquement. Haskell est typé statiquement et peut être compilé ou interprété
Zachary K
1
@ZacharyK Erlang possède un système d'exécution; Haskell est compilé dans la majorité des cas (programmes écrits).
m3th0dman
1

Outre les raisons évoquées par les autres, il existe un cas d'utilisation particulièrement important pour choisir une interprétation ad hoc plutôt que toute forme de compilation ou toute approche hybride.

Dans le cas où un langage de programmation est utilisé comme protocole de communication , et lorsque la latence de réponse est importante, il est plus logique d'éviter de perdre du temps sur la compilation et tout prétraitement possible.

Cela s'applique aux langues des agents, par exemple, ou à la façon dont, par exemple, Tcl / Tk est normalement utilisé.

Une autre raison possible de s'en tenir à l'interprétation est lorsqu'un interprète de langue est utilisé pour l'amorçage lui-même ou un langage de niveau supérieur plus élaboré, et sa simplicité est plus importante que les performances du processus d'amorçage.

Pour presque tous les autres cas d'utilisation possibles, la compilation (ou une approche hybride) convient mieux.

SK-logic
la source