Pourquoi la dactylographie dynamique est-elle si souvent associée aux langues interprétées?

les gens de question Simple: je fais beaucoup de programmation (professionnellement et personnellement) dans des langages compilés comme C++/Java et dans des langages interprétés comme Python/Javascript. Personnellement, je trouve que mon code est presque toujours plus robuste lorsque je programme dans des langages statiquement typés. Cependant, presque tous les langages interprétés que je rencontre utilisent le typage dynamique (PHP, Perl, Python, etc.). Je sais pourquoi les langages compilés utilisent la dactylographie statique (la plupart du temps), mais je ne peux pas comprendre l'aversion pour le typage statique en langage interprété de conception.

pourquoi la déconnexion abrupte? Fait-elle partie de la nature des langues interprétées? La programmation orientée objet?

39
demandé sur Suraj Jain 2009-09-08 17:00:36

7 réponses

question intéressante. BTW, je suis l'auteur / mainteneur de phc (compilateur pour PHP), et je fais mon doctorat sur les compilateurs pour les langues dynamiques, donc j'espère que je peux offrir quelques idées.

je pense qu'il y a une supposition erronée ici. Les auteurs de PHP, Perl, Python, Ruby, Lua, etc n'ont pas conçu de "langages interprétés", ils ont conçu des langages dynamiques, et les ont implémentés en utilisant des interprètes. Ils l'ont fait parce que les interprètes sont plus facile à écrire que les compilateurs.

la première implémentation de Java a été interprétée, et c'est un langage statiquement typé. Il existe des interprètes pour les langues statiques: Haskell et OCaml ont tous deux des interprètes, et il y avait un interprète populaire pour C, mais c'était il y a longtemps. Ils sont populaires parce qu'ils permettent un REPL , ce qui peut rendre le développement plus facile.

cela dit, Il ya une aversion à la dactylographie statique dans le une communauté linguistique dynamique, comme on pouvait s'y attendre. Ils croient que les systèmes de type statique fournis par C, C++ et Java sont verbeux, et ne valent pas la peine de l'effort. Je pense que je suis d'accord avec cela, dans une certaine mesure. Programmer en Python est bien plus amusant que C++.

Pour aborder les points des autres:

  • dlamblin dit : "Je n'ai jamais vraiment senti qu'il y avait quelque chose de spécial dans la compilation vs l'interprétation qui a suggéré dynamique sur le typage statique."Eh bien, vous êtes très mal là. La Compilation de langages dynamiques est très difficile. Il y a surtout la déclaration eval à considérer, qui est largement utilisée dans Javascript et Ruby. phc compile PHP à l'avance, mais nous avons encore besoin d'un interpréteur d'exécution pour gérer eval s. eval ne peut pas non plus être analysé statiquement dans un compilateur d'optimisation, bien qu'il existe une technique cool si vous n'avez pas besoin de sonorité.

  • à la réponse de damblin à Andrew Hare : vous pourriez bien sûr effectuer une analyse statique dans un interprète, et trouver des erreurs avant run-time, ce qui est exactement ce que fait Haskell ghci . Je m'attends à ce que le style d'interprète utilisé dans les langues fonctionnelles l'exige. dlamblin a bien sûr raison de dire que l'analyse ne fait pas partie de l'interprétation.

  • la réponse D'Andrew Hare est basée sur l'hypothèse erronée des questionneurs, et a également les choses de la mauvaise façon autour. Cependant, il soulève une question intéressante: "à quel point l'analyse statique des langues dynamiques est-elle difficile?". Très très dur. En gros, vous aurez un doctorat pour décrire comment ça marche, ce qui est exactement ce que je fais. Voir également le point précédent.

  • la réponse la plus correcte à ce jour est que de Ivo Wetzel . Cependant, les points qu'il décrit peuvent être traités à l'exécution dans un compilateur, et de nombreux compilateurs existent pour Lisp et Scheme qui ont ce type de liaison dynamique. Mais, oui, c'est délicat.

47
répondu Paul Biggar 2017-05-23 10:31:25

les langages de l'utilisation typage dynamique, car il n'y a pas d'étape de compilation pour faire de l'analyse statique. Les langages compilés font une analyse statique au moment de la compilation ce qui signifie que toute erreur de type est signalée au développeur pendant qu'ils travaillent.

il est plus facile de comprendre si vous considérez qu'un langage statiquement typé a un compilateur qui applique les règles de type en dehors du contexte d'exécution. Les langues interprétées sont jamais analysé de manière statique si les règles de type doivent être appliquées par l'interprète dans le contexte de l'exécution.

4
répondu Andrew Hare 2009-09-08 13:04:56

je pense que c'est à cause de la nature des langues interprétées, elles veulent être dynamiques, donc vous pouvez changer les choses à l'exécution. En raison de cela un compilateur ne sait jamais exactement quel est l'état du programme après la ligne suivante du code a été excecuted.

imaginez le scénario suivant (en Python):

import random
foo = 1

def doSomeStuffWithFoo():
    global foo
    foo = random.randint(0, 1)

def asign():
    global foo
    if foo == 1:
        return 20
    else:
        return "Test"


def toBeStaticallyAnalyzed():
    myValue = asign()

    # A "Compiler" may throw an error here because foo == 0, but at runtime foo maybe 1, so the compiler would be wrong with its assumption
    myValue += 20


doSomeStuffWithFoo() # Foo could be 1 or 0 now... or 4 ;)
toBeStaticallyAnalyzed()

comme vous pouvez l'espérer, un compilateur n'aurait aucun sens dans cette situation. Acutally il pourrait vous en avertir le possibilité que "mavaleur" peut-être autre chose qu'un Numéro. Mais dans JavaScript cela échouerait car si "myValue" est une chaîne, 20 serait aussi converti implicitement en chaîne, donc aucune erreur ne se produirait. Donc vous pourriez avoir des milliers d'Avertissements inutiles partout, et je ne pense pas que ce soit l'intention d'un compilateur.

la flexibilité vient toujours avec un prix, vous devez jeter un oeil plus profond à votre programme, ou le programmer plus soigneusement, en d'autres termes vous êtes le compilateur dans des situations comme celle-ci.

donc votre solution en tant que compilateur? - Fixer avec un "essayez:" à l'exception" :)

4
répondu Ivo Wetzel 2009-09-08 14:43:45

compilateurs + types statiques = code machine efficace

Compilateurs + types dynamiques = code machine inefficace

considère le pseudo suivant:

function foo(a, b) {
    return a+b
}

un langage statique sera capable de savoir (par déclaration ou inférence) que a et b sont des entiers, et sera compilé jusqu'à

%reg = addi a,b

ou quelque chose de similaire.

un compilateur pour une dynamique la langue devrait émettre le code à

1. Vérifier qu'ils types de a et b

2. manipuler chaque caisse ou combinaison de caisses

%reg1 = typeof a
beq %reg1, int, a_int_case
beq %reg1, float, a_float_case
beq %reg1, string, a_string_case

label a_int_case
%reg1 = typeof b
beq %reg1, int, a_int_b_int_case
beq %reg1, float, a_int_b_float_case
beq %reg1, string, a_int_b_string_case

label a_int_b_int_case
%out = addi a,b
goto done

label a_int_b_float_case
%tmp = mkfloat a
%out = addf %tmp,b
goto done

... Etc. I can't finish

alors que vous pourriez générer du code machine plus intelligent que cela, vous ne seriez pas en mesure d'aider à générer beaucoup de code -- ce qui rend la compilation pas une victoire majeure pour un langage dynamique.

puisque les interprètes sont beaucoup plus faciles à écrire, et la compilation ne vous fait pas beaucoup de bien, pourquoi ne pas écrire un interprète?

(Juste-à-temps compilateurs effectivement avoir des informations sur le type et permet de compiler le droit à l'instruction. Ils ont en fait plus d'informations que les systèmes de type statique, et peuvent théoriquement faire encore mieux. Tout assembleur est simulé; toute ressemblance avec du code réel qui pourrait fonctionner sur une machine réelle est purement fortuite.)

2
répondu Sean McMillan 2009-10-27 13:19:01

C'est peut-être parce que L'une de mes principales langues interprétées est Perl et que L'une de mes langues compilées est Objective-C, mais je n'ai jamais vraiment senti qu'il y avait quelque chose de spécial dans la compilation par rapport à l'interprétation qui suggérait la dynamique par rapport à la dactylographie statique.

je pense qu'il est clair que les deux parties regardent l'autre et pensent, "il y a des avantages à cela."Il est plus facile dans plusieurs applications d'obtenir une certaine flexibilité de type dynamique, alors qu'il peut être plus facile pour maintenir quelque chose qui est statiquement typé et appliqué.

je suis en désaccord avec Andrew Hare explication si. Alors qu'un langage purement interprété devrait être ajouté dans une étape de prétraitement, et donc ne pas être purement interprété afin d'avertir le programmeur avant l'exécution d'erreurs de frappe statique, il n'empêche pas de lancer une erreur de type à l'exécution au moment où elle se produit. Ainsi, l'absence de compilation ne signifie pas qu'aucune vérification de type statique ne peut avoir lieu. Mais étant donné que l'obtention d'une erreur de type à l'exécution n'est pas aussi utile que l'obtention d'une erreur à la compilation, ou lors d'une vérification avant vol, je peux voir comment l ' "avantage" de la dactylographie statique dans cette situation peut sembler être plus une nuisance, et donc se jeter en faveur des avantages de la dactylographie dynamique apporter.

si vous saviez depuis le début que vous préférez garder vos types statiques parce que personnellement vous écrivez un meilleur code maintenable en conséquence, et vous conceviez votre interprétation langue, rien ne devrait vous empêcher de concevoir la langue comme statically typed un.

pour citer le langues interprétées article wiki " en théorie, n'importe quelle langue peut être compilée ou interprétée, de sorte que cette désignation est appliquée purement en raison de la pratique courante de mise en œuvre et non d'une propriété sous-jacente d'une langue."

Il y a un décent article wiki sur juste la dactylographie.

1
répondu dlamblin 2017-05-23 11:54:53

les langages D'interprétation dactylographiés dynamiquement vous donnent plus de liberté dans la façon dont vous programmez. Cela permet à la méta-programmation d'être faisable. Il permet de créer des variables au moment de l'exécution. Permet de créer des hashs anonymes et des tableaux anonymes à n'importe quel moment pendant le temps d'exécution sans jamais déclarer quoi que ce soit avant la main. Il permet de saisir des informations indéterminées dans un hash sans jamais déclarer toutes les clés à l'avance. Vous pouvez avoir des sous-routines créées d'entrée aléatoire indéterminée. Vous pouvez également alimenter un code de programme qui peut être exécuté dynamiquement. Les langages interprétés libèrent les chaînes qui limitent la programmation en général. Vous êtes limité à ce que vous tapez dans le fichier source avec des langues statiquement dactylographiées. Vous pouvez faire plus avec moins dans un langage dynamiquement tapé.

la plupart des robots fabriqués aujourd'hui traitent davantage des langages interprétés parce que l'information doit être déterminée à l'exécution et que de nouvelles variables doivent être fait pour stocker cette information à l'exécution. L'apprentissage automatique repose sur l'interprétation de l'information. Nous-mêmes, en tant qu'êtres humains, sommes des interprètes, c'est pourquoi les robots sont conçus de cette manière. Le futur est vraiment interprété. Bien sûr, vous avez besoin de langages statiquement dactylographiés pour construire des interprètes de sorte que les langages statiquement dactylographiés ne disparaîtront jamais à moins que les interprètes ne soient construits en code assembleur à l'avenir. La plupart des interprètes sont construits sur des langues statiquement typées de nos jours.

les langues interprétées excellent dans un environnement dynamique. Si vous pouvez interpréter de nouveaux codes/informations à l'exécution, alors pourquoi pas. Si votre vraiment bon à la programmation dynamique alors vous pouvez créer du code qui peut créer des variables et des hachures sans jamais taper tout. Vous pouvez réduire le nombre de lignes de façon drastique si vous travaillez avec d'énormes quantités de données. Vous pouvez utiliser un dumper de données pour imprimer toutes vos informations parce que les langues interprétées gardent généralement la trace du type de variables à l'exécution permettant à ceci d'être possible. Vous ne pouvez pas faire cela dans barebones c++. La seule fois où c++ et c savent ce qui se passe, c'est au moment de la compilation. Après ça, tout seul, à moins que vous ne mettiez en œuvre quelque chose vous-même.

qui veut tellement être attaché au fichier source ces jours-ci, surtout quand vous travaillez dans des environnements dynamiques. Tout ce que tu fais, c'est limiter ton potentiel. Une fois que votre cou dans le code interprété dynamiquement et vous retournez à n'importe quel statically langage dactylographié, vous trouverez plus difficile de réduire votre code parce que votre pensée encore dans un État d'esprit illimité. Votre esprit doit revenir à être limité à nouveau à ce qui est tapé dans le fichier source.

, Dans le sens de styles de programmation: Le code statiquement typé produit des résultats statiques. Le code saisi dynamiquement produit des résultats dynamiques ou statiques.

si vous allez programmer quelque chose qui ne change jamais le comportement autre que ce qui est les langues connues alors statiquement dactylographiées sont idéales pour cela. Si vous traitez avec le comportement dynamique alors les langues dynamiquement typées sont mieux adapté pour ces cas. Tout dépend de la situation la plupart du temps.

chaque langue a ses hauts et ses bas. Il faut choisir et choisir judicieusement.

0
répondu stealth 2018-01-13 23:22:27

je pense que le typage statique le rend plus facile pour les compilateurs et c'est la principale (si pas seulement) raison pour laquelle il est présent dans les langues compilées.

pour les langues interprétées il est plus facile de supposer que les variables n'ont pas de type (seules les valeurs ont) parce qu'elles ne sont pas considérées comme un placer pour les données qui doivent s'inscrire à l'intérieur mais plutôt étiquette pour les données qui flotte quelque part sur le tas.

si le programmeur veut il peut toujours affirmer que variable contient une valeur de type donné (par exemple sur la cession). Il n'y a aucune raison de l'intégrer dans la langue. Bien sûr que non le même type de contrôle que vous avez pour les langages compilés.

vous pourriez probablement avoir un langage dans lequel vous devez déclarer explicitement le type de chaque variable, mais si vous ne le faites pas, il est beaucoup plus facile de faire des choses intéressantes qui avec la dactylographie statique exigerait de programmeur des types génériques complexes soigneusement conçus.

d'autre part. Connaissez-vous un langage compilé dynamiquement (statically, not JIT)?

-1
répondu Kamil Szot 2009-09-08 13:23:37